简体   繁体   中英

Instantiating class with interfaces in c#

Hi this might be trivial but I am trying to understand the class instantiation using interface. So below is my code:

public interface IRepository
{
    string GetMemberDisplayName();
}

public class Repository : IRepository
{
    private readonly Manager _manager;

    public Repository() {}

    public Repository(string connectionName)
    {
        _manager = new Manager(connectionName);
    }

    public string GetMemberDisplayName(string ID)
    {
        return "FooFoo";
    }
}

Now in another class that uses the repository class functionality has instantiated it as follows:

public class LogServiceHelper
{
    readonly IRepository _alrAttendance;
    readonly IRepository _alrUsers;

    public LogServiceHelper()
    {
        _alrAttendance = new Repository("value1");
        _alrUsers = new Repository("value2");
    }

    public string GetMemberName(string empId)
    {
        return _alrUsers.GetMemberDisplayName(empId);
    }
}

My question is if this is correct way to instantiate a class with parameterized constructor. And if yes, then second question is why do we need interface in this case. We could directly instantiate the class without creating the interface?

Yes, that's how to invoke a parameterized constructor, but no, that's not what you should be doing.

As you have it, LogServiceHelper has a hard dependency on the Repository class, and so you are right, the interfaces don't buy you anything. However, if they were injected :

public LogServiceHelper(IRepository attendanceRepo, IRepository userRepo)
{
    _alrAttendance = attendanceRepo;
    _alrUsers = userRepo;
}

You suddenly gain the benefits of abstraction. Notably that a unit test could pass in fake repositories, and that you can switch to another implementation of IRepository without changing LogServiceHelper .

The next question is then "Who creates the Repository concrete class?". For that, I refer you to the variety of DI/IoC containers out there, such as Autofac, Unity, and NInject.

We could directly instantiate the class without creating the interface?

This is indeed true and it might work without any problem. But then we are coming to the crucial questions:

  • Is my code testable, how would I test this piece of code?
  • Could I easily change the behavior without changing LogServiceHelper

If you don't rely on the abstraction, the answer to the above questions is unfortunately, no . Luckily there is something called SOLID and the D stands for Dependency Injection Principle .

public LogServiceHelper(IRepository alrAttendance, IRepository alrUsers)
{
    _alrAttendance = alrAttendance;
    _alrUsers = alrUsers;
}

So, with this simple change, you made decoupling of the moduls and all of a sudden you are relying on the abstraction which gains a lot of benefits to design.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM