DI的五个W,IoC,因为它让我的大脑爆炸

时间:2013-03-07 00:16:59

标签: c# interface dependency-injection inversion-of-control

所以控制反转是一个模糊的描述,因此依赖注入成为新的定义。这是一个非常非常强大的解决方案,对于从未遇到过这种情况的人来说,这可能会让人感到困惑。

因此,在我不想成为头灯的鹿的过程中,我读了一遍。我找到了几本很棒的书和在线帖子。但就像所有美好的事物一样,更多的问题出现而不是答案。

这个问题,吸收了一个未知项目的变量,一旦它们被引入我的项目就会被实现。

解决方案:

public interface ISiteParameter
{
    Guid CustomerId { get; set; }
    string FirstName { get; set; }
    string LastName { get; set; }
    string Phone { get; set; }
}

我的注射器:

public interface IInjectSiteParameter
{
     void InjectSite(ISiteParameter dependant);
}

然后我创造了这个:

public class SiteContent : IInjectSiteParameter
{
    private ISiteParameter _dependent;

    #region Interface Member:
    public void InjectSite(ISiteParameter dependant)
    {
        _dependant = dependant;
    }
    #endregion
}

然后用共享引用实现它作为Fed变量我创建了一个类实现的类:

public class SiteParameters : ISiteParameter
{    
   public Guid Customer Id { get; set; }
   public string FirstName { get; set; }
   public string LastName  { get; set; }
   public string Phone { get; set; }
}

现在SiteParameters Class将由另一个项目引用;这将允许我随时随地实际调用这些属性:

ISiteParameter i = new ISiteParameter();
MessageBox.Show(i.Guid + i.FirstName + i.LastName + i.Phone);

这是实施,但我的问题是...... 我什么时候使用?

  • 构造函数注入
  • Setter Injection
  • 界面注入

你什么时候使用其中一个?对于我提到的任务,我应该执行如此艰巨的任务来调整对其他项目所做的任何更改?

我的思维过程中是否脱离了曲线?

2 个答案:

答案 0 :(得分:3)

由Mark Seemann撰写的Dependency Injection in .NET第4章

构造函数注入应该是DI的默认选择。它解决了类需要一个或多个依赖项的最常见情况。如果依赖类绝对不能在没有保证有价值的依赖的情况下运行。

仅当您正在开发的类具有良好的本地默认值并且您仍希望启用调用方提供类的依赖项的不同实现时,才应使用属性注入。如果框架要求您具有默认构造函数(如ASP.NET页面),也可以使用属性注入。

当依赖关系随每个方法调用而变化时,最好使用方法注入。当依赖项本身表示值时可能就是这种情况,但是当调用者希望向消费者提供有关调用操作的上下文的信息时,通常会看到这种情况。

答案 1 :(得分:1)

尽可能使用Constructors传递depdendencies,而不是通过方法调用注入。

例如:

public interface IWebHost 
{ 
   string DoSomething(string input); 
} 

public class FooManager 
{
   private IWebHost _host; 
   public FooManager(IWebHost host)
   {  
      _host = host; 
   } 

   public void Process()
   { 
      // do something with _host 
   }
} 

这有很多好处,但我认为最有益的是:

  • 我的依赖项是预先指定的,一个人被遗漏的可能性较小。
  • 我可以使用Dependency Injection存储库自动为我构建。

有些情况下这样做是不可能或不切实际的,但是大多数情况都可以通过注入一个为我进行构造的工厂来解决。

另一个例子:

public interface IConnection : IDisposable 
{
   string DoSomething(string input); 
   // implement IDisposable
}

public interface IConnectionFactory 
{
   IConnection CreateConnection(); 
} 

public class DerpConnection : IConnection 
{
    // implementation
} 

public class DerpConnectionFactory : IConnectionFactory 
{
  // We only return DerpConnections from this factory.  

  IConnection CreateConnection() { return new DerpConnection(); } 
}

public class BarManager 
{ 
   private IConnectionFactory _connectionFactory; 
   public BarManager(IConnectionFactory connectionFactory)
   {   
      _connectionFactory = connectionFactory;
   } 

   public void Manage()
   {
      using(var connection = _connectionFactory.CreateConnection()) 
      { 
        // do something here. 
      } 
   }
}

DI框架只需知道此示例中的IConnectionFactory,而Factory实现直接构造DerpConnection。在单元测试中,我可以轻松地模拟工厂和IConnection响应。

无法做到这一点的情景,通常表示某种cross-cutting concern,或者该类比它需要的要复杂得多(并且违反{{3} })