我正面临一项设计挑战,我似乎无法以令人满意的方式解决这个挑战。我有一个包含所有共享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对象中。现在我写道它似乎很明显,但它仍然是我唯一可以提出的解决方案,我想在这里询问是否有其他人有他们想提出的不同解决方案?
我对解决方案的一个问题是,我可以看到自己陷入命名我的继承类型 - 我的意思是......这是一个人,你还有什么称呼它?无论如何,希望你能为我提供一些想法。
另外,我对现有的技术并不熟悉,实际上,说实话,我只是很难掌握我目前正在使用的技术。所以,如果我说了一些矛盾或混乱的话,我希望你能从帖子的其余部分中理解得足以得到我所要求的东西。
答案 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)
我可以想到解决这个问题的几种方法。
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();
}
}
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。