依赖注入选择

ter*_*tyl 14 c# dependency-injection

我正在寻找依赖注入,我可以看到它的好处,但我遇到了它创建的语法问题.我有这个例子

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }

   public List<Product> GetProducts()
   {
    return dx.GetProducts();
   }
}
Run Code Online (Sandbox Code Playgroud)

问题是我不想写

BusinessProducts bp = new BusinessProducts(dataContextImplementation);
Run Code Online (Sandbox Code Playgroud)

我会继续写

BusinessProducts bp = new BusinessProducts();
Run Code Online (Sandbox Code Playgroud)

因为我觉得第一种选择只是感觉不自然.我不想知道BusinessProduct"依赖"什么来获取产品,我也觉得它使我的代码更难以理解.

这种方法有什么替代方法,因为我想保留我创建对象的原始语法,但我仍然希望能够在单元测试时伪造依赖关系,还是这个依赖注入框架可以为我做什么?

我在c#编码,但欢迎其他语言的替代品

tva*_*son 9

我使用工厂作为我的上下文并注入它,如果提供的工厂为null,则提供合适的默认值.我这样做有两个原因.首先,我使用数据上下文作为工作范围对象的单元,因此我需要能够在需要时创建它们,而不是保持一个.其次,我主要使用DI来提高可测试性,而仅仅考虑次要因素.

所以我的商业产品类看起来像:

public class BusinessProducts
{
     private IDataContextFactory DataContextFactory { get; set; }  // my interface

     public BusinessProducts() : this(null) {}

     public BusinessProducts( IDataContextFactory factory )
     {
          this.DataContext = factory ?? new BusinessProductsDataContextFactory();
     }

     public void DoSomething()
     {
          using (DataContext dc = this.DataContextFactory().CreateDataContext())
          {
             ...
          }
     }
Run Code Online (Sandbox Code Playgroud)

另一种方法是使工厂属性可公开设置,并通过设置属性注入备用工厂.无论哪种方式,如果你想保留null构造函数,你需要提供一个默认值.


tro*_*skn 6

你可以创建一个工厂.DI容器最适合在设置时发生的布线 - 而不是在运行时(因为这看起来是这样).工厂可以以不同的方式实施,具体取决于它需要的可插拔性,以及需要使用它的地方数量.


Owe*_*wen 6

我通常会有一个空的构造函数,它使用一个实体实例(或由IoC创建的实例),并使用DI.即

public class BusinessProducts
{
   IDataContext _dx;

   BusinessProducts()
   {
      _dx = new SolidDataContext();
   }

   BusinessProducts(IDataContext dx)
   {
      _dx = dx;
   }
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以使用DI来覆盖单元测试测试中的默认实例.


Bry*_*tts 5

你的感受虽然合理,但却是错误的。

依赖注入模式是控制反转原理的直接应用。

这意味着,不是您的类控制它所使用的其他类的实例,而是反转该关系并向其提供依赖项。

因此,您的类自然会通过构造函数参数或属性公开它们的依赖项。对这种结构表现出蔑视表明你还没有真正理解这种模式。