5

我目前处于多个相当复杂的系统的设计阶段,这些系统共享共同的功能(例如,两者都有客户关系管理(CRM)和销售功能)。因此,我试图提取域的公共部分并在两个应用程序中重用它。

假设我有应用程序 A 和应用程序 B,它们都使用 CRM 功能。在大多数情况下,CRM 功能是相同的,但两个应用程序都喜欢增加一些与 CRM 相关的东西。

我想创建一个实现 CRM 系统基本版本的库,例如将客户抽象为

interface ICustomer {
  string CustomerNumber {get;set;}
}

基础库有 ICustomer 的基本实现

class Customer: ICustomer

应用程序 A 现在可以增强它:

interface IACustomer : ICustomer {
    bool ReceivesNewsletter {get;set;}
}

class ACustomer : Customer, IACustomer {
   ...
}

同样,B 也有自己的变体:

interface IBCustomer : ICustomer {
    string NickName {get;set;}
}

class BCustomer : Customer, IBCustomer {
    ....
}

出于抽象的目的,我从不在基础库中实例化具体类型,而是使用工厂或 DI 容器,例如:

interface ICrmFactory {
    ICustomer CreateCustomer();
}

A 和 B 相应地实现工厂,以便分别创建 ACustomers 或 BCustomers。

这是我的意思的UML图(未显示应用程序B): 应用程序设计

对于持久性,我使用 NHibernate。A 和 B 都提供自己的映射(按代码映射)以包含额外的属性。另外,A 定义 IACustomer 为 ACustomer 的代理类型,B 定义 IBCustomer 为 BCustomer 的代理类型。

我现在可以使用 NHibernate 来处理 A 和 B 中的实体,例如 A

session.QueryOver<ACustomer>()
    .Where(c=>c.ReceivesNewsletter)
    .List()

现在假设我想对基础库中的客户做一些事情(例如在某种服务对象中)。我刚刚制作了一个非常简单的版本的原型,到目前为止这似乎工作正常:

session.QueryOver<ICustomer>()
   .Where(c => c.CustomerNumber == "1234ABC")
   .List()

也就是说,我可以在QueryOver中使用特定实体的代理类型的基类,NHibernate会创建正确的查询,例如在A中:

SELECT
    this_.Id as Id0_0_,
    this_.CustomerNumber as Customer2_0_0_,
    this_.ReceivesNewsletter as Receives3_0_0_ 
FROM
    ACustomer this_ 
WHERE
    this_.CustomerNumber = @p0;
@p0 = '1234ABC' [Type: String (4000)] 

我的问题

这些查询会始终按预期工作吗?我可以在基本库的查询中始终安全地使用代理接口的基本类型吗?NHibernate 是否总能找到“正确”的实体类型和要检索的表?或者是否会在某些情况下对查询效率产生不利影响 b/c NHibernate 需要进行猜测工作?在这种情况下我应该注意的任何其他陷阱?

我在文档中找不到有关此的信息。这种方法可以让我巧妙地将某些域的公共部分移动到他们自己的基础库中,但我想确保它有效。

4

1 回答 1

1

我认为这种情况没有问题。特别是因为在每个应用程序中只有一个 ICustomer 实现。

即使您对每个应用程序都有多个实现,您也可能会遇到按 id 加载的一些问题(session.Load(42),因为可能有多个具有该 id 的客户,具体取决于您的映射)。但是接收客户列表的查询仍然有效。

当我过去研究与 NHibernate 类似的问题时,我阅读了这篇文章 - 它谈论的是派生基类而不是接口,但它是相同的想法:http ://codebetter.com/jameskovacs/2011/02/ 16/getload-polymorphism-in-nhibernate-3/

NHibernate 不会猜测工作 - 在初始化时,它会为任何给定类型构建所有映射的存储,当您为任何类型编写查询时,它会找到它映射的正确类型,从它继承并相应地查询.

于 2013-01-24T15:50:04.203 回答