在此之前被标记为重复之前我已经四处寻找我的问题的答案,但我的情景比其他类似问题更具体,我不会认为像#34;这是一种不好的做法"应用
我正在研究一些设计选择,以便在使用Entity Framework进行DDD方法后对域进行建模,我对将依赖项注入实体的方法感兴趣。确切地说,我认为值得注入的唯一依赖项是属于我正在使用的聚合根的域对象的工厂,或者是围绕静态类的包装器,如下所示:
public class CurrentTimeProvider : ITimeProvider
{
public DateTime GetTime()
{
return DateTime.Now();
}
}
包装器的目的是使单元测试更容易,并且我不喜欢这种情况下的双重调度模式,因为它破坏了封装。
示例实体:
public class ActivationToken
{
protected ITimeProvider TimeProvider;
public ActivationToken(ITimeProvider timeProvider)
{
TimeProvider = timeProvider;
}
public virtual DateTime? ConsumedTime { get; protected set; }
public virtual void Consume()
{
ConsumedTime = TimeProvider.GetTime();
}
}
所以我的问题是如何让Entity Framework在创建实例时提供我的依赖?
答案 0 :(得分:1)
这很困难的部分原因在于,从概念上讲,您混合了 injectibles 和 newables 。
有关差异的解释,请参阅http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/。
DDD中的实体符合“新的”类别。应用程序服务,域服务,存储库等是可以注意的。
您的示例的另一种方法是使用“方法注入”并将ITimeProvider
直接传递到Consume
方法:
public class ActivationToken
{
public ActivationToken()
{
}
public virtual DateTime? ConsumedTime { get; protected set; }
public virtual void Consume(ITimeProvider timeProvider)
{
ConsumedTime = timeProvider.GetTime();
}
}
这仍允许使用模拟时间提供程序进行单元测试,并确保实体字段仅与实体的状态有关。您可以通过将ITimeProvider
注入到将调用Consume
方法的应用程序服务/用例中来获取ViewPager
的实例。
答案 1 :(得分:0)
我认为最简单的方法是避免构造函数注入并注册一个可以从no-arg构造函数访问的全局服务定位器,例如:
public class ActivationToken
{
protected ITimeProvider TimeProvider;
public ActivationToken()
{
TimeProvider = ServiceLocator.Instance.GetService<ITimeProvider>();
}
public virtual DateTime? ConsumedTime { get; protected set; }
public virtual void Consume()
{
ConsumedTime = TimeProvider.GetTime();
}
}