【发布时间】:2011-08-02 22:41:43
【问题描述】:
我有几个支付交易基础类型的子类(信用卡、支票、现金、billMeLater 等)。每个子类都有自己的存储库,因为每个子类都有自己的属性和获取方式。我需要能够搜索支付交易,而我已经走上了一条最终导致更多头痛的道路。诀窍是,有时客户需要搜索金额或客户姓名等常见属性,有时客户需要搜索信用卡号或银行路由号码等特定于支付类型的属性......但域级搜索方法需要能够返回所有类型的交易基础。
我有以下抽象级别:
带有 SearchTransactions() 方法的 WCF 层。
带有 SearchTransactions() 方法的域层。
具有多个存储库的数据层,每个存储库都有一个 Search() 方法 (特定于付款类型)。
数据库(通过 EF)具有典型的 DBA 所需的难以理解的混乱
你会怎么做?
编辑:
为了补充上下文,以下是一些可能的支付类型及其基础的示例:
public abstract class TransactionBase
{
public int TransactionId { get; set; }
public decimal Amount { get; set; }
}
public class CreditCardTransaction : TransactionBase
{
public string CardNumber { get; set; }
public int ExpirationMonth { get; set; }
public int ExpirationYear { get; set; }
}
public class CheckTransaction : TransactionBase
{
public string BankAccountNumber { get; set; }
public string RoutingNumber { get; set; }
}
因此,客户端应该能够通过一种方法搜索 CardNumber、RoutingNumber、Amount 等。如果客户端搜索 Amount(base 上的参数),该方法应该返回 CreditCardTransaction 和 CheckTransaction。如果客户端搜索 BankAccountNumber,它应该只返回 CheckTransactions。
客户要求和早期解决方案:
客户端要求一次调用即可搜索多种交易类型。客户并不关心他们作为参数传入的内容,除非他们需要多次调用来涵盖所有支付类型。我之前的一个想法是使用带有搜索条件的类。然后我可以拥有搜索更具体的支付类型属性的搜索条件类的子类。像这样:
public class TransactionSearchCriteriaBase
{
public int TransactionId { get; set; }
public decimal Amount { get; set; }
}
public class CreditCardTransactionSearchCriteria : TransactionSearchCriteriaBase
{
public string CardNumber { get; set; }
public int ExpirationMonth { get; set; }
public int ExpirationYear { get; set; }
}
因此,如果客户端想要搜索 Amount 等常见属性,他们会传入 TransactionSearchCriteriaBase。如果他们传入 CreditCardTransactionSearchCriteria,他们最终会搜索信用卡交易。例如:
var listOfTransactions = _transactionService.Search(new CreditCardTransactionSearchCriteria{ Amount = 10m, CardNumber = "1111" });
我将几乎不可避免的 switch/if 块替换为存储库工厂,该存储库工厂根据传入工厂的标准对象类型返回适用存储库的列表。
兔子洞越来越深。我想要少一点兔子洞。
另一条信息:
由于我们在 EF 3.5 中执行此操作,因此我们没有 POCO 支持。因此,我们不将 EF 生成的对象视为域对象。我们的存储库将各种断开连接的 EF 对象映射到域对象,并将它们返回给调用它们的域服务。
【问题讨论】:
标签: c# domain-driven-design repository