我遇到了一个我认为值得在这里讨论的困境。
我有一组域对象(如果你愿意,你也可以称它们为实体),它们从一个单独的 DAL 中获取一些数据,这些数据由 IoC 解析。
我正在考虑使我的系统非常可扩展,并且我正在徘徊是否也可以由 IoC 解决这些实体。
让我举一个愚蠢的例子。
假设我有一个网站,我有以下界面:
public interface IArticleData
{
int ID { get; }
string Text { get; set; }
}
这个概念是,DAL 实现了这样的接口,也是一个通用IDataProvider<TData>
接口,之后 DAL 变得易于替换。并且有以下类,它使用它:
public class Article
{
private IArticleData Data { get; set; }
public int ID
{
get { return Data.ID; }
}
public int Text
{
get { return Data.Text; }
set { Data.Text = value; }
}
private Article(IArticleData data)
{
Data = data;
}
public static FindByID(int id)
{
IDataProvider<IArticleData> provider = IoC.Resolve<IDataProvider<IArticleData>>();
return new Article(provider.FindByID(id));
}
}
这使得整个系统独立于实际的 DAL 实现(在示例中为IDataProvider<IArticleData>
)。
然后想象一下这个功能还不够的情况,我想扩展它。在上面的例子中,我没有任何选择,但如果我让它实现一个接口:
public interface IArticle
{
int ID { get; }
string Text { get; set; }
}
public class Article : IArticle
{
...
}
然后,我删除了对 Article 类的所有依赖项,并开始将其解析为带有 IoC 的瞬态 IArticle 组件。
例如,在城堡中:<component id="ArticleEntity" service="IArticle" type="Article" lifestyle="transient" />
在此之后,如果我必须扩展它,那就很简单了:
public class MyArticle : Article
{
public string MyProperty { ..... }
}
我所要做的就是将配置更改为:<component id="ArticleEntity" service="IArticle" type="Article" lifestyle="transient" />
因此,任何使用相关系统的人都可以替换所有类,就像在配置中重写一行一样简单。所有其他实体也将正常工作,因为新实体将实现与旧实体相同的功能。
顺便说一句,这似乎是“关注点分离”哲学的一个很好的解决方案。
我的问题是,这是正确的做法吗?经过一番认真的思考,我想不出更好的方法来做到这一点。我也考虑过 MEF,但它似乎面向制作插件,而不是替换或扩展这样的系统已经完整的部分。
我阅读了许多关于该主题的 SO 问题(以及其他来源),最值得注意的是: 我应该如何使用 IoC/依赖注入处理我的实体/域对象?和 IoC,你把容器放在哪里?
而且我还担心我会遇到以下页面中描述的问题: http ://martinfowler.com/bliki/AnemicDomainModel.html和 http://hendryluk.wordpress.com/2008/05/10/应该由 ioc 管理域实体/
还有一件事:这会增加整个系统的可测试性,不是吗?
你怎么看?
编辑:另一种选择是为这些实体创建工厂模式,但IoC.Resolve<IArticle>
比IoC.Resolve<IArticleFactory>().CreateInstance()