在应用程序中使用DI与共享库

时间:2011-05-11 02:59:59

标签: c# oop orm dependency-injection

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

我还有一些基于Microsoft的模式和组合的复合应用程序块(CAB)构建的应用程序。实践小组(P& P)。是的,我知道这已经很老了,但我是一名兼职开发人员,单人工作,无法负担更新现有框架的任何内容。

这就是我的问题所在:我一直在运用我的OO设计技巧,每当进行大量重构时,我都试图从程序方法转向更多OO方法。当然,OO设计的一个主要方面是将操作放在它们使用的数据附近,这意味着我的ORM对象需要在适当的地方添加功能。当我考虑到我在CAB中使用P& P的Object Builder DI容器并且我将移植到我的ORM对象中的大部分功能将需要访问我的应用程序所公开的服务时,这证明是一个真正的头脑。 / p>

换句话说,假设我有一个名为“Person”的共享业务对象(原创,我知道),我有两个应用程序与一个人完全不同的事情。应用程序A提供了一组服务,Person对象需要具有DI,以便它能够采用当前遍布我的服务层的一些方法。应用程序B还有一组不同的服务,IT需要将这些服务转移到人员对象中。

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

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

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

另外,我对现有的技术并不熟悉,实际上,说实话,我只是很难掌握我目前正在使用的技术。所以,如果我说了一些矛盾或混乱的话,我希望你能从帖子的其余部分中理解得足以得到我所要求的东西。

3 个答案:

答案 0 :(得分:3)

听起来你正在打破Single Responsibility Principle

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

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

答案 1 :(得分:1)

我同意Cameron MacFarland的观点:你正在打破SRP。

  

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

放置来自B的A AND功能的数据和功能是两个过多的责任。对SRP的应用几乎总是会导致在单独的类(数据结构和对象)中分离数据和功能。因此,使用Cameron MacFarlands消化可能是最好的方法。

答案 2 :(得分:0)

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

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

Apporach1


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;
 }
}

Person接口项目需要引用IPerson1和IPerson2,或者您可以在Person接口项目本身中声明IPerson1和IPerson2。