2009-12-12 60 views
3

我是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. 
} 

谢谢你的建议。

回答

2

我不认为有一个完美的解决方案,但你可以避免将持久性代码放入域类中,方法是将默认货币(和类似的属性)存储在其他类中(例如“DomainDefaults”),并让它从另一段代码l初始化ogically坐落在域对象的“上方”。当然,你必须确保在创建任何域对象之前调用初始化代码。如果没有初始化,它可能会抛出一个异常,所以你至少可以很容易地理解它。

所以构造变得

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

而且你的地方NHibernate的初始化后不久,你会打电话:

DomainDefaults.DefaultCurrency = Repository.GetCurrency("JPY") 
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,统一或)该货币提供商默认进入方法你实例付款方式:

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

-1 from me - 我相信还有另一种获取货币信息的方法,而不必诉诸于持久性或依赖注入。 – duffymo 2009-12-12 14:07:57

2

我不明白为什么这必须拥有的任何东西做与持久性所有。

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

This SO question告诉我CultureInfo是C#的等价物。也许你应该在你的设计中尝试一下,留下像“日元”这样的字符串,并坚持不懈。

+0

对于货币来说,这是一个好主意,但它并不能真正解决基本问题。你真正所做的就是将持久性从数据库转移到操作系统注册库。因此,如果例如你转移到Unix,区域存储会有所不同,因此我需要更改我的域模型... – thrag 2009-12-13 05:39:40

+0

10转到Unix?我会假设你正在考虑Mono。我对Java更熟悉,所以我假设 - 也许不正确 - 如果我正在编写Web应用程序,Locale/Culture将会从客户端浏览器设置的HTTP标头中获得。 – duffymo 2009-12-13 11:52:01