mnsr
mnsr

Reputation: 12437

C# How to use interfaces

This is a relatively straight forward question. But I was wondering what the correct usage is for accessing a method inside a separate project through the use of an interface.

Project: Test.ClassLibrary

Interface:

public interface ITest
{
    string TestMethod();
}

Class:

public class Test : ITest
{
    public string TestMethod()
    {
        return "Test";
    }
}

Project: Test.Web

Controller:

public class HomeController : Controller
{
    private ITest test;
    public ActionResult Index()
    {
        return Content(test.TestMethod());
    }

}

The above returns a NullReferenceException. I'm assuming it's because the controller gets to the interface, and doesn't know where to go next.

What's the best way to fix this? Do I have to reference the Test class in the controller or can I some how get away with only having a reference to ITest?

Upvotes: 20

Views: 54429

Answers (4)

Clint
Clint

Reputation: 6509

What ?

Interfaces are basically a contract that all the classes implementing the Interface should follow. They looks like a class but has no implementation.

In C# Interface names by convention is defined by Prefixing an 'I' so if you want to have an interface called shapes, you would declare it as IShapes

Now Why ?

Improves code re-usability

Lets say you want to draw Circle, Triangle. You can group them together and call them Shapesand have methods to draw Circle and Triangle But having concrete implementation would be a bad idea because tomorrow you might decide to have 2 more Shapes Rectangle & Square. Now when you add them there is a great chance that you might break other parts of your code.

With Interface you isolate the different implementation from the Contract


How to use them ?

Usage Scenario Day 1

You were asked to create an App to Draw Circle and Triangle

interface IShapes
{
   void DrawShape();
}

class Circle : IShapes
{
    
    public void DrawShape()
    {
        Console.WriteLine("Implementation to Draw a Circle");
    }
}

class Triangle : IShapes
{
    public void DrawShape()
    {
        Console.WriteLine("Implementation to draw a Triangle");
    }
}
static void Main()
{
     List <IShapes> shapes = new List<IShapes>();
     shapes.Add(new Circle());
     shapes.Add(new Triangle());

     foreach(var shape in shapes)
     {
         shape.DrawShape();
     }
}

Usage Scenario Day 2

If you were asked add Square and Rectangle to it, all you have to do is create the implentation for it in class Square: IShapes and in Main add to list shapes.Add(new Square());

Upvotes: 2

Anthony Pegram
Anthony Pegram

Reputation: 126952

  • You never instantiate ITest test, you only declare it.
  • Your Test class doesn't inherit from the interface.

You need to update your class declaration

public class Test : ITest // interface inheritance 
{

And in your controller, instantiate test.

ITest test = new Test();

As you get further along, you'll want to explore techniques for injecting the Test instance into the controller so that you do not have a hard dependency upon it, but just on the interface ITest. A comment mentions IoC, or Inversion of Control, but you should look into various Dependency Inversion techniques techniques (IoC is one of them, dependency injection, etc).

Upvotes: 27

cHao
cHao

Reputation: 86575

First off, you need to have your Test class inherit/implement ITest.

class Test : ITest
{
    public string TestMethod() { return "test"; }
}

Then, in your controller class, you need to initialize test -- whether directly, or in the constructor.

public class HomeController : Controller
{
    public ITest test = new Test();
    public ActionResult Index()
    {
        return Content(test.TestMethod());
    }
}

Although in many cases, you should prefer to create the ITest outside of the constructor and pass it in or something.

Upvotes: 4

Daniel Mallott
Daniel Mallott

Reputation: 298

The class needs to read:

public class Test : ITest

in its declaration.

Upvotes: 5

Related Questions