将 DI 与跨应用程序的共享库结合使用

本文关键字:结合 共享 DI 应用程序 | 更新日期: 2023-09-27 17:55:52

我面临着一个设计挑战,我似乎无法以令人满意的方式解决。 我有一个类库程序集,其中包含我所有共享的ORM对象(使用EntitySpaces框架)。 这些对象用于 2 个或多个不同的应用程序,这就是它们位于自己的程序集中的原因。 这个设置对我来说已经工作了4 +年。

我还在Microsoft模式与实践组(P&P)的复合应用程序块(CAB)上构建了几个应用程序。 是的,我知道这真的很旧,但我是一名兼职开发人员,一个人的商店,负担不起更新到当前框架的费用。

这就是我的问题所在:我一直在锻炼我的OO设计技能,每当进行实质性的重构时,我都会尝试从程序方法转向更多的OO方法。 当然,OO设计的一个主要方面是将操作放置在它们使用的数据附近,这意味着我的ORM对象需要在适当的时候添加功能。 当我考虑到我在CAB中使用P&P的Object Builder DI容器并且我将移动到ORM对象中的许多功能将需要访问我的应用程序公开的服务时,这证明是一个真正的头疼问题。

换句话说,假设我有一个名为"Person"的共享业务对象(我知道是原始的),并且我有两个应用程序对一个人做完全不同的事情。 应用程序 A 提供了一组服务,Person 对象需要对这些服务进行 DI 处理,以便采用当前遍布我的服务层的一些方法。 应用程序 B 还具有一组不同的服务,IT 需要将这些服务DI到人员对象中。

考虑到P&P对象生成器如何使用属性修饰和类型反射来解决依赖关系,我不明白如何做到这一点。 简而言之,我有一个共享对象,当在各种应用程序中使用时,我需要注入依赖项,以便它可以执行特定于该应用程序的某些操作。

我能想到的唯一方法是从 Person 对象继承应用程序 A 和 B 中的新类型。 然后,我将我的非共享功能和 DI 代码添加到此特定于应用程序的专用 Person 对象中。 现在我写了,这似乎很明显,但它仍然是我能想出的唯一解决方案,我想在这里问一下是否有其他人有不同的解决方案,他们想提出

我的解决方案会遇到的一个问题是,我可以看到自己陷入了命名继承类型的困境 - 我的意思是......这是一个人,那你还会怎么称呼它? 无论如何,希望你能对我有一些想法。

此外,我对当前的技术并不时髦,老实说,我只是勉强掌握了我目前正在使用的技术。 因此,如果我说了一些矛盾或令人困惑的话,我希望你能从帖子的其余部分理解到足以理解我所问的内容。

将 DI 与跨应用程序的共享库结合使用

听起来你违反了单一责任原则。

Person对象应该只保存人员记录的数据。然后,服务将接收Person对象并对其进行操作,而不是在执行该操作的Person对象上使用方法。

一个典型的示例是填充 Person 对象。假设应用 A 从 Web 服务中获取数据,应用 B 从数据库中获取数据。在这些情况下,我会调用某种Storage服务来获取Person对象。然后,该存储的实现可以特定于每个应用程序,并由应用放入 IOC 中,而不是尝试在共享程序集中使用通用接口。

我同意卡梅隆·麦克法兰的观点:你正在破坏SRP。

当然是OO设计的一个主要方面 正在将操作放置在靠近 他们使用的数据,这意味着 我的 ORM 对象需要有 添加到其中的功能 适当

从 A 放置数据和功能,从 B 放置 AND 功能是两个太多的责任。与SRP相邻几乎总是会导致将数据和功能分离到单独的类(数据结构和对象)中。因此,使用Cameron MacFarlandssugestion可能是最好的方法。

我可以想到几种方法来解决这个问题。

  • 分别分离出特定于每个人/应用程序的行为。在应用程序本身中使用 setter 执行依赖项注入。

附录1


public interface IPerson 
{
 IPersonApp1 Person1 {get; set;}
 IPersonApp2 person2 {get; set;}
}
class Person : IPerson
{
 IPerson1 Person1 {get; set;}
 IPerson2 Person2 {get; set;}
}

   public interface IPerson1
  {
    // App1 specific behavior here
     void App1SpecificMethod1();
  }
  class Person1: IPerson1
   {
     void App1SpecificMethod1()
      {
       // implementation
      }
   }
class App1 
{
   IPerson objPerson;
   // Dependency injection using framework
   App1(IPerson objPerson)
  {
    this.objPerson = objPerson;
    // Dependency injection using setter
    this.objPerson.Person1 = new Person1();
  }
}

  • 分别分离出特定于每个人/应用程序的行为。在 Person 构造函数中执行依赖项注入。

Apporach2


class Person : IPerson
{
 IPerson1 Person1 {get; private set;}
 IPerson2 Person2 {get; private set;}
 // DI through constructor. If the type IPerson1 or IPerson2 are not registered, it will be set to null.
 Person(IPerson1 objPerson1, IPerson2 objPerson2)
 {
   this.Person1 = objPerson1;
   this.Person2 = objPerson2;
 }
}
人员接口项目需要引用 IPerson1 和 IPerson2,

或者您可以在人员接口项目本身中声明 IPerson1 和 IPerson2。