领域驱动设计问题

时间:2009-12-12 13:39:51

标签: c# domain-driven-design

我是DDD的新手,如果我没有正确使用这些条款,请原谅我。

我正在使用C#MS / SQL和NHibernate。

我有一个班级电话付款,这笔付款有一个PaymentCurrency,每个都是数据库中的一个实体。

行。在我的域模型中,我希望能够创建付款为

Payment p = new Payment( 100 ) // automatically uses the default currency (defined in the db )

Payment p = new Payment( 100, Repository.GetCurrency( "JPY" ) ) // uses Yen defined in the db.

但在我看来,为了使用dfault货币初始化我的域对象,我需要使用持久性知识来污染域模型。即在我完成默认的付款构造函数之前,我需要从数据库中加载默认付款对象。

我可视化的构造函数就像

一样
public Payment( int amount ) {
   Currency = Repository.LoadDefaultCurrency();  // of cource defualt currency would be a singleton
}

public Payment( int amount, Currency c ) {
   Currency = c; // this is OK since c is passed in from outside the domain model.
}

感谢您的建议。

3 个答案:

答案 0 :(得分:2)

我认为没有一个完美的解决方案,但是您可以通过将默认货币(和类似属性)存储在其他类(例如“DomainDefaults”)上来避免将持久性代码放入域类中它从逻辑上位于域对象“上方”的另一段代码初始化。当然,您必须确保在创建任何域对象之前调用初始化代码。如果没有初始化,它应该抛出异常,所以你至少可以很容易地捕获它。

所以构造函数变为

public Payment( int amount )
{
   Currency = DomainDefaults.DefaultCurrency;
}

在初始化NHibernate之后的某个地方,你会打电话:

DomainDefaults.DefaultCurrency = Repository.GetCurrency("JPY")

答案 1 :(得分:2)

我不明白为什么这与持久性有任何关系。

如果我是用Java编写的,我会从应用程序的Locale中获取默认货币。

This SO question告诉我CultureInfo是C#的等价物。也许你应该在你的设计中尝试,并留下像“JPY”和持久性的字符串。

答案 2 :(得分:0)

您的答案是 依赖注入

使用它并且不要使用配置来规范模型。 如果您需要创建具有所需金额和货币的付款 - 只需这样做:

var currency = injectedCurrencyRepository.GetByName("JPY");
var p = new Payment(100.00m, currency);

不要假设默认货币。

或者在最坏的一端你可以添加inteface:

public interface ICurrencyProvider {
   Currency GetCurrency();
}
// Implment the default:
public class DefaultCurrencyProvider : ICurrencyProvider {
   public Currency GetCurrency() {
      return new Currency("AUD");
   }
}

// And the Payment constructor will look like:
public Payment(decimal amount, ICurrencyProvider currencyProvider) {
   c = currencyProvider.GetCurrency();
}

因此,您可以默认情况下将该货币提供商(使用Windsot,Unity或其他)注入您实例化付款的方法:

var p = new Payment(100.00m, defaultCurrencyProvider);