使用C#中的接口实例化类

时间:2019-02-06 21:57:01

标签: c# class interface instantiation parameterized-constructor

嗨,这可能是微不足道的,但是我试图使用接口来理解类实例化。所以下面是我的代码:

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";
    }
}

现在,在另一个使用存储库类功能的类中,已将其实例化如下:

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);
    }
}

我的问题是,这是否是用参数化构造函数实例化类的正确方法。如果是,那么第二个问题是为什么在这种情况下我们需要接口。我们可以直接实例化该类而无需创建接口吗?

2 个答案:

答案 0 :(得分:2)

是的,这就是调用参数化构造函数的方法,但是,不是,这不是您应该做的。

正如您所拥有的,LogServiceHelperRepository类有严格的依赖性,因此您是对的,接口不会为您带来任何好处。但是,如果它们被注射

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

您突然获得了抽象的好处。值得注意的是,单元测试可能会通过伪造的存储库,并且您可以切换到IRepository的另一种实现而无需更改LogServiceHelper

接下来的问题是“谁创建Repository具体类?”。为此,我向您介绍了各种DI / IoC容器,例如Autofac,Unity和NInject。

答案 1 :(得分:0)

  

我们可以直接实例化该类,而无需创建   界面?

这确实是事实,并且可能会毫无问题地起作用。但是随后我们遇到了关键问题:

  • 我的代码可以测试吗,我将如何测试这段代码?
  • 是否可以轻松更改行为,而无需更改LogServiceHelper

如果您不依赖抽象,那么上述问题的答案很不幸,。幸运的是,有一个叫做SOLID的东西,D代表Dependency Injection Principle

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

因此,通过这个简单的更改,您就使模块解耦了,突然之间您就依赖于抽象,这对设计有很多好处。