[英]Dependency Injection and assembly references
我有一个我希望是MVC应用程序中依赖注入的基本问题,我一直无法找到满意的答案。 我的应用程序包含一个MVC 3项目,一个服务层类库(SL)和一个数据访问类库(DAL)。 SL和DAL都包含各自的接口和实现。 MVC项目引用了SL和DAL项目。 MVC项目将创建DAL的实现并将其注入到接受DAL接口的SL构造函数中。
我担心的是为了让SL接受DAL接口作为参数,它还需要对DAL项目的引用(接口碰巧存在但也是实现),这似乎违反了DI,因为现在MVC和SL项目需要引用DAL程序集。
简而言之,将DAL接口移动到自己的项目中是否更有意义,这样SL只需要引用接口项目而不是实现项目? MVC项目显然需要引用接口和实现项目,DAL也需要引用接口项目。 这似乎是一种更干净的做事方式,即使它为我的解决方案增加了另一个项目,这并没有给我带来太多麻烦。 我也看到了在SL中存储DAL接口的建议,并且有DAL参考SL,但这对我来说似乎不对。 任何见解或建议都表示赞赏。 谢谢!
看看洋葱建筑:
http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
http://jeffreypalermo.com/blog/the-onion-architecture-part-2/
http://jeffreypalermo.com/blog/the-onion-architecture-part-3/
让UI程序集引用所有服务和业务逻辑程序集是完全正确的。 服务层显然应该引用不应该依赖于任何更高级别的基础结构程序集。
真正的组件必须将它们的接口及其实现放在单独的程序集中。
这允许您像加载项一样动态加载适当的实现。 通常它也是避免循环引用的唯一方法。 作为示例,DAL需要知道模型(业务类),并且模型可能希望通过DAL调用延迟加载依赖模型,这会创建循环引用(.NET禁止循环程序集引用)。 如果接口位于单独的程序集中,则DAL和Model程序集都引用了两个接口程序集,并通过构造函数获取依赖项。
// Assembly: Model contracts
public interface IModelA
{
IModelB ModelB { get; }
...
}
public interface IModelB
{
...
}
public interface IModelFactory
{
IModelA CreateModelA();
IModelB CreateModelB();
}
// Assembly: DAL contracts, references Model contracts
public interface IDAL
{
IModelA LoadA(int id);
IModelB LoadB(int id);
}
// Assembly: Model implementation, references Model and DAL contracts
public class ModelA : IModelA
{
private IDAL _dal;
public ModelA (IDAL dal)
{
_dal = dal;
}
private IModelB _modelB;
public IModelB ModelB
{
get {
if (_modelB == null) {
_modelB = _dal.LoadB(5);
}
return _modelB;
}
}
}
// Assembly: DAL implementation, references Model and DAL contracts
public class DAL : IDAL
{
private IModelFactory _modelFactory;
public DAL(IModelFactory _modelFactory)
{
_modelFactory = modelFactory;
}
public IModelA LoadA(int id)
{
IModelA modelA = _modelFactory.CreateModelA();
// fill modelA with data from database
return modelA;
}
public IModelB LoadB(int id)
{
IModelB modelB = _modelFactory.CreateModelB();
// fill modelB with data from database
return modelB;
}
}
正如规则所说,只要您依赖接口而不是具体实现,它就没问题。 所以你可以做的是将你的接口放在单独的程序集中,并在任何你想要的地方引用它们。
引用具有混凝土类型的程序集可能是一个问题,但这取决于您要实现的目标。 通过让服务仅依赖于抽象,您可以实现松散耦合的代码。 这提高了可维护性。
让BL程序集仅引用包含抽象(而不是实现)的程序集,允许您独立部署部分软件。 比如说您希望将软件部署到不同的客户,并且您有多种DA层,但不希望将所有DA风格部署到所有客户(例如,因为他们需要为每个DA层付费,或者可能你试图保护你的知识产权)。
因此,如果分离不是部署的关注点,则不必创建单独的程序集。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.