真正的组件必须在单独的程序集中有它们的接口和它们的实现。
这允许您像加载项一样动态加载适当的实现。通常它也是避免循环引用的唯一方法。例如,DAL 需要知道模型(业务类),并且模型可能希望通过 DAL 调用延迟加载依赖模型,这会创建循环引用(.NET 禁止循环程序集引用)。如果接口位于单独的程序集中,则 DAL 和模型程序集都具有对这两个接口程序集的引用,并通过构造函数获取依赖项。
// 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;
}
}