C# DI:将实体与存储库关联

C# DI:将实体与存储库关联,c#,architecture,dependency-injection,C#,Architecture,Dependency Injection,我对这个概念很陌生。我要做的是创建一个工厂,它将返回一个用于存储库函数的对象。没问题。因此,我在main()中创建了一个具体工厂的实例,并将其存储在App的静态属性中,但我的实体位于单独的dll中。将存储库传递给构造函数中的每个实体类有意义吗?这感觉不对。我的问题是:如何最好地让我的实体知道他们应该使用哪个存储库 我的应用程序部分类看起来像 public partial class App : Application { private static ICalDataAccess _daqFa

我对这个概念很陌生。我要做的是创建一个工厂,它将返回一个用于存储库函数的对象。没问题。因此,我在main()中创建了一个具体工厂的实例,并将其存储在App的静态属性中,但我的实体位于单独的dll中。将存储库传递给构造函数中的每个实体类有意义吗?这感觉不对。我的问题是:如何最好地让我的实体知道他们应该使用哪个存储库

我的应用程序部分类看起来像

public partial class App : Application
{
 private static ICalDataAccess _daqFactory;

 public static ICalDataAccess DataAccessFactory
 {
   set { _daqFactory = value; }
   get { return _daqFactory; }
 }
}
也许需要更多的代码

public class Widget
{
    public string Description { get; set; }
    public int ID { get; set; }

    private IWidgetRepository _widgetRepository;
    public Widget(IWidgetRepository WidgetRepository)
    {
        _widgetRepository = WidgetRepository;
    }

    public void Save()
    {
        _widgetRepository.Save(this);
    }
}

我在这里做了什么异常的事情吗?

我认为一般的建议是让您的实体免于持久性问题。也就是说,您有一些代码检索实体并使用它们执行任何需要完成的工作,从而生成新的、删除的或修改的实体,然后调用代码将这些实体提交到相应的存储库(或者如果您有跟踪或检测修改的实体的内容,如EF或NHibernate,则请求保存)

这样,您的实体根本不需要了解存储库

我通常创建一个UnitOfWork助手类,它通过“public RepositoryFactory repositories{get;}”属性公开我的所有存储库,这样,只要提供UnitOfWork类的一个实例,我就可以访问我的所有数据源。然后,可以通过IoC将UnitOfWork注入任何需要数据访问的类

有关此主题的一些推荐阅读:


您的描述听起来更像是服务定位器模式,而不是依赖注入。依赖项注入通常看起来像任何需要某些服务对象(如数据访问)来完成其工作的对象都会将该服务作为其构造函数的参数接收。

为什么要让实体知道存储库?难道不是相反吗?同样的问题。通常,您会希望通过更好的设计来解决这个问题。好吧,这样我就可以执行类似于_widget.Save()的操作。似乎比Factory.WidgetRepository.Save(\u小部件)更简单、更干净。问题是,如果IWidgetRepository在它的构造函数中,小部件将需要一个具体的实例。我在这里偏离了基准吗?相关:想提出另一个问题:如何在不将存储库传递给实体的情况下干净地实现延迟加载(假设我们不使用DDD)?示例:一个团队包含一个玩家列表,其中包含他们自己的复合数据。如果实体不知道存储库,那么最终将得到一个笨拙而冗长的存储库。ie TeamRepository.GetPlayers(aTeam);更糟糕的是,客户需要了解这个系统的复杂性。“我认为一般的建议是让您的实体免于持久性问题。”为什么?实体不能通过接口保存自己吗?理论上可以。它适用于非常简单的场景,但当您需要修改多个实体时,很快就会变得难以管理。突然之间,您需要在单个类中包含多个存储库或对其他实体的引用。这种编排通常更易于从实体外部进行管理,从而形成更易于维护的更干净的域模型。嗯,你能给我举个例子吗?我无法想象一个实体需要修改许多其他实体。如果是这样,这肯定会由另一个类处理。在我现在工作的系统中,存储库实际上只对域对象执行crud操作。比如说,您向客户添加了地址,但您也有具有地址的公司。您是独立于所属实体保存地址,还是同时向客户和公司提供对地址存储库的访问权限?例如,如果客户只能使用属于一组特定公司的地址,谁来验证地址是否有效?当您需要保存多个实体时,谁控制交易边界?当每个实体都只是自救时,它不知道自己是否是更大事物的一部分。所有这些“跨实体关注点”都是有问题的。我希望我不是在争论,我真的在努力学习。我认为客户会验证其地址是否有效,或者将其自身传递给其他业务规则类,然后将其自身传递给存储库的save方法。save方法可能会展平对象,然后调用存储过程来实际执行保存。我想这就是我的建议。对象需要更新自身,因此它在其构造函数中接收一个数据访问对象,这有助于实现该功能。