.net 当许多相似但不同的类需要许多相似但不同的依赖项时,如何最好地实现依赖项注入?

.net 当许多相似但不同的类需要许多相似但不同的依赖项时,如何最好地实现依赖项注入?,.net,dependency-injection,mvp,.net,Dependency Injection,Mvp,我正在VisualStudio.NET4.0中开发一个Windows应用程序,在这里我使用MVP模式,并试图在整个应用程序中学习和应用依赖注入原则。但我很难理解如何最好地处理一种特殊情况。我为这么长的解释提前道歉,但我不知道我是否可以说得足够具体 该应用程序是一个通用的记录保存应用程序,用于保存许多不同类型的记录,其中一些记录相互关联,另一些记录与其他记录无关。我们使用的每种不同的记录类型在应用程序中都构成了一个独特的“特性”。因此,应用程序的启动屏幕本质上是一个交换机,用户可以从中选择要导航到

我正在VisualStudio.NET4.0中开发一个Windows应用程序,在这里我使用MVP模式,并试图在整个应用程序中学习和应用依赖注入原则。但我很难理解如何最好地处理一种特殊情况。我为这么长的解释提前道歉,但我不知道我是否可以说得足够具体

该应用程序是一个通用的记录保存应用程序,用于保存许多不同类型的记录,其中一些记录相互关联,另一些记录与其他记录无关。我们使用的每种不同的记录类型在应用程序中都构成了一个独特的“特性”。因此,应用程序的启动屏幕本质上是一个交换机,用户可以从中选择要导航到的功能

当他们做出选择时,该功能的窗口(视图)打开,他们可以从该窗口执行与该功能相关的各种操作。大多数功能(如客户、订单)都有一些用户可以执行的常见操作(创建新记录、打开现有记录、保存更改、打印等)。但是,有些操作特定于该功能(例如,特定于订单功能的验证操作)。我的问题在于弄清楚如何在每个特性中执行操作

因为我使用的是MVP,所以功能窗口有一个演示者,当用户启动该功能的任何操作时,该演示者都会做出响应。但是,由于我想遵循单一责任原则,我不希望演示者成为一个上帝类,并且真正知道如何创建记录、保存、打印等。因此,我的想法是定义单独的类来处理每个操作,就像使用.create()方法实现ICreateOrders一样,一个带有.Save()方法的ISaveOrders实现,等等。为了给它们取个名字,我将它们称为“解析器”,因为它们实际解析了该操作的请求。其中一些常见的解析器可能具有基本实现(例如,基本FeatureSave类),因为许多代码在各个功能中都是相似的,但如果需要,每个功能都需要能够具有特定的实现。这种方法提出了几个问题

首先,除了该功能的窗口外,我希望这些操作能够从应用程序中的其他位置启动。例如,我不仅能够在“订单”功能窗口中打开订单记录,还希望能够从“客户”功能中选择“查看订单”,并自动打开和显示该客户的订单记录。为了实现代码重用,我希望使用相同的IOpenders实现来完成这项工作,而不管请求是从应用程序的何处发起的。因此,在Orders窗口的presenter中简单地嵌入所需的解析器似乎不是一个选项

所以我的想法是创建一个FeatureService类,它将保存一组Feature对象。在应用程序启动时,我会从数据库中获得对登录用户有效的所有功能的列表,然后我会迭代该列表,为每个功能创建一个功能对象,并将其添加到FeatureService的集合中。然后,当我需要在一个特性中从另一个特性中启动操作时,我可以通过将FeatureService对象注入源类,从中获取目标特性,然后使用它来执行操作来实现。但是我也不想让Feature类成为God类,所以这相当于将所有单独的解析器从Orders presenter移动到Feature类

但要实现这一点,必须向Feature对象注入它可能需要的所有解析器,而不知道用户是否将执行这些操作。对于一些更复杂的特性,可能会注入20或30个不同的解析器,这显然像是构造函数注入滥用。虽然这可以防止Feature对象成为God类,因为它只是将每个操作传递给其注入的解析器,但这似乎是错误的。当一个对象变成这样的“上帝协调器”时,这种用法正确吗

我的另一个问题是关于这些物体的体积。对于某些客户,可能有50个或更多的单独功能可用(毫无疑问,随着时间的推移,还需要更多的功能)。因此,当我在启动时创建这些功能对象,并且我的容器将所有这些解析器依赖项注入到每个对象中时,我将创建数百个对象(例如,每个功能40个功能X 20个解析器),无论我是否访问过其中一些功能。一个典型的用户会话可能只涉及到一些特性,所以像这样在启动时创建这么多对象似乎是浪费。我可以放弃,让Feature对象在内部执行ServiceLocation以获取其解析程序,但如果有更好的方法,我愿意使用它


我不知道从这里到哪里去。我试图寻找并找到关于这方面的例子和信息,但我不知道我是否知道要搜索什么。非常感谢任何人提供的任何指导或见解。

如果我理解正确,您尝试使用
ICreateOrders
ISaveOrders
构建的内容是

通常,存储库可能如下所示:

public interface IRepository<TEntity>
{
    TEntity GetByKey(int key);

    TEntity CreateNew();

    void Save(TEntity entity);

    void Delete(TEntity entity);
}
IRepositoryFactory
创建一个实现非常简单,因为这将直接映射到您的DI容器:

private sealed class FrameworkSpecificRepositoryFactory
    : IRepositoryFactory
{
     private readonly Container container;

     public FrameworkSpecificRepositoryFactory(Container container)
     {
         this.container = container;
     }

     public IRepository<TEntity> CreateRepository<TEntity>()
     {
         return this.container.GetInstance<IRepository<TEntity>>();
     }
}
私有密封类框架指定位置工厂
:IRepositoryFactory
{
专用只读容器;
公共框架指定位置工厂(容器)
{
this.container=容器;
}
公共伊雷波西酒店
private sealed class FrameworkSpecificRepositoryFactory
    : IRepositoryFactory
{
     private readonly Container container;

     public FrameworkSpecificRepositoryFactory(Container container)
     {
         this.container = container;
     }

     public IRepository<TEntity> CreateRepository<TEntity>()
     {
         return this.container.GetInstance<IRepository<TEntity>>();
     }
}