代码之家  ›  专栏  ›  技术社区  ›  Venemo

将IoC用于实体或域模型的扩展性是否正确?

  •  1
  • Venemo  · 技术社区  · 16 年前

    我遇到了一个进退两难的问题,我认为值得在这里讨论。

    我有一组域对象(如果您愿意,您也可以称它们为实体),它们从单独的DAL获取一些数据,DAL通过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
    {
        ...
    }
    

    例如,在Castle中: <component id="ArticleEntity" service="IArticle" type="Article" lifestyle="transient" />

    在这之后,如果我必须扩展它,那将是这么简单:

    public class MyArticle : Article
    {
       public string MyProperty { ..... }
    }
    

    我所要做的就是将配置更改为: <组件id=“ArticleEntity”service=“IArticle”type=“Article”livelity=“transient”/gt;

    顺便说一句,这似乎是“关注点分离”哲学的一个很好的解决方案。

    经过一番认真的思考,我想不出更好的办法。我也考虑过MEF,但它似乎是面向制作插件,而不是替换或扩展这样一个系统中已经完整的部分。

    我读了很多关于这个话题的问题(以及其他来源),其中最值得注意的是: How should I handle my Entity/Domain Objects using IoC/Dependency Injection? IoC, Where do you put the container?

    http://martinfowler.com/bliki/AnemicDomainModel.html http://hendryluk.wordpress.com/2008/05/10/should-domain-entity-be-managed-by-ioc/

    还有一件事:这将增加整个系统的可测试性,不是吗?

    你怎么认为?

    另一种选择是为这些实体创建工厂模式,但是 IoC.Resolve<IArticle> 这比 IoC.Resolve<IArticleFactory>().CreateInstance()

    1 回复  |  直到 9 年前
        1
  •  3
  •   pmarflee    16 年前

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

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

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