【问题标题】:Mixing encapsulation and dependency injection混合封装和依赖注入
【发布时间】:2012-03-20 03:06:12
【问题描述】:

我有一个用作数据模型的类。我会这样简化:

public class DataModel
{
   public bool IsDataModelActive {get; internal set;}
}

因此,使用我的 DLL 的程序员只会看到他们需要的东西,而不会冒险破坏任何东西。

另一方面,我想在使用 DataModel 的课程中​​使用 DI。所以我必须创建一个接口:

public interface IDataModel
{
   bool IsDataModelActive {get;}
}

所以我在课堂上注入了这个:

public class Class1
{
   IDataModel dataModel;

   public Class1(IDataModel dataModel)
   {
      this.dataModel = dataModel
   }
}

在这种情况下,我无法访问 dataModel.IsDataModelActive 的设置器。

我发现最好的补丁是在接受注射后施放:

public class Class1
{
   DataModel dataModel;

   public Class1(IDataModel dataModel)
   {
      this.dataModel = (DataModel)dataModel
   }
}

这有助于单元测试,但它打破了 DI 的整个概念。如果我有另一个实现IDataModel 的类怎么办?

你/你会使用什么策略?

【问题讨论】:

    标签: c# interface dependency-injection


    【解决方案1】:

    如果接口 IDataModel 不允许您从 DataModel 外部访问 setter,那么(希望这并不奇怪)您不应该需要从 DataModel 外部访问 setter。 DataModel 本身或可以看到 setter 的东西应该负责设置该值。

    【讨论】:

    • 这是有道理的。所以我必须在将我的二传手暴露给世界和不使用 DI 之间做出选择。真可惜!
    • 还是我这方面的设计不好?
    • 可能只是糟糕的设计(无意冒犯)。 IsDataModelActive 是真还是假的定义是什么?
    • DataModel 应该作为一个过程的结果返回,所以它不应该被我的代码外部的任何东西实例化。所以 IsDataModelActive 在返回之前会被进程修改。
    • 在这种情况下,初始化过程使用的接口应该是IActivateableDataModel或类似的东西,正如@Sunny所建议的那样,并且该接口传递给用户不需要设置IsDataModelActive 应该是你已经拥有的IDataModel 接口。 DataModel 类可以而且应该实现两者。
    【解决方案2】:

    Class1 是否公开可见 - 即暴露给消费者?如果没有,则创建另一个内部接口 IDataModelInt : IDataModel 并在那里提供 setter。将第二个用于您的内部工作。

    【讨论】:

    • 这似乎是最好的主意。它迫使我发送两次相同的对象(依赖项)作为两个参数,但这是一个不错的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多