我对依赖注入很新,我写了一个很棒的小应用程序,就像Mark Seemann告诉我的那样,世界很棒。我甚至添加了一些额外的复杂性,只是为了看看我是否可以使用DI处理它。我可以,快乐的日子。
然后我把它带到一个真实世界的应用程序,并花了很长时间挠挠脑袋。 Mark告诉我,我不允许使用'new'关键字来实例化对象,我应该让IoC为我做这件事。
然而,说我有一个存储库,我希望它能够返回一个列表,因此:
public interface IThingRepository
{
public IEnumerable<IThing> GetThings();
}
当然至少有一个这个接口的实现必须实例化一些东西?而且,允许ThingRepository创建一些事物似乎并不是很糟糕,因为无论如何它们都是相关的。
我可以改为绕过POCO,但在某些时候我将不得不将POCO转换为业务对象,这需要我新的东西。
这种情况似乎每当我想要一些组合根中无法知道的事情时就会出现(即我们稍后才会发现这些信息 - 例如在查询数据库时)。
有谁知道在这种情况下最佳做法是什么?
答案 0 :(得分:1)
Mark告诉我,我不允许使用'new'关键字来实例化对象
这不是马克·西曼告诉你的,或者他的意思。您必须在一侧明确区分服务(由组合根控制)和另一侧的基元,实体,DTO,视图模型和消息。服务是injectables and all other types are newables。您应该只阻止在服务类型上使用new
。例如,防止新增字符串会很愚蠢。
由于在您的示例中该服务是repository,因此假设存储库返回域对象似乎是合理的。域对象是新手,没有理由不手动new
。
答案 1 :(得分:1)
除了Steven的回答之外,我认为特定工厂可以新建它为其创建的特定匹配实现。
另外,请检查this answer,特别是评论,其中说明了有关新增实例的内容。
示例:
public interface IContext {
T GetById<T>(int id);
}
public interface IContextFactory {
IContext Create();
}
public class EntityContext : DbContext, IContext {
public T GetById<T>(int id) {
var entity = ...; // Retrieve from db
return entity;
}
}
public class EntityContextFactory : IContextFactory {
public IContext Create() {
// I think this is ok, since the factory was specifically created
// to return the matching implementation of IContext.
return new EntityContext();
}
}
答案 2 :(得分:0)
感谢大家的回答,他们引导我得出以下结论。
Mark在我正在阅读的书中区分了稳定和不稳定的依赖关系(“.NET中的依赖注入”)。可以随意创建稳定的依赖项(例如字符串)。应该将不稳定的依赖项移到接缝/接口后面。
依赖是指与我们正在编写的汇编不同的汇编。
不稳定依赖项是以下任何一种
所以这一切都很好。
但是,我经常在同一个装配体中隐藏接缝背后的东西。我发现这对测试非常有帮助。例如,如果我正在进行复杂的计算,则无法一次性测试整个计算 井 。如果我将计算分成许多较小的类并隐藏在接缝后面,那么我可以轻松地将任何arbirtary中间结果注入计算类。
所以,有了一个好老的想法,这些是我的结论:
在回答我原来的问题时,可以从混凝土工厂中实例化具体物体。