1

我遇到了一个我认为值得在这里讨论的困境。

我有一组域对象(如果你愿意,你也可以称它们为实体),它们从一个单独的 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()

4

1 回答 1

3

我想你可能把事情复杂化了。您是否需要将 Article 替换为另一种实现 IArticle 的类型?

当您有一个依赖于较低级别组件的较高级别组件并且您希望较高级别组件依赖于该组件的抽象时,最好使用 IoC 容器,因为较低级别组件在内部执行一些操作,使很难测试更高级别的组件,例如数据库访问。或者,较低级别的组件可能代表应用程序中的特定策略,该策略可以与其他策略互换,例如数据库网关,它抽象出使用供应商特定数据库 API 的细节。

由于 Article 是一个简单的 POCO 样式类,因此通过 IoC 容器创建它的实例不太可能获得任何好处。

于 2009-11-19T20:42:42.757 回答