2009-12-12 9 views
3

Je suis nouveau à DDD alors s'il vous plaît pardonnez-moi si je n'utilise pas les termes correctement. J'utilise C# MS/SQL et NHibernate.Question de conception guidée par domaine

J'ai un appel de classe Paiement et ce paiement a un PaymentCurrency, chacun d'eux est une entité dans la base de données.

OK. Dans mon modèle de domaine que je veux être en mesure de créer paiement soit

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

ou

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

Mais il me semble que pour initialiser mon objet de domaine avec la monnaie défault je dois polluer le modèle de domaine avec la connaissance de la persistance. c'est-à-dire que, avant de pouvoir terminer le constructeur de paiement par défaut, j'ai besoin de charger l'objet de paiement par défaut à partir de la base de données.

Le constructeur est somehting je visualise comme

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

Merci pour vos conseils.

Répondre

2

Je ne pense pas qu'il existe une solution parfaite, mais vous pouvez éviter de placer le code de persistance dans les classes de domaine en ayant la devise par défaut (et les propriétés similaires) stockée sur une autre classe (par exemple "DomainDefaults") initialisé à partir d'un autre morceau de code que l ogiquement "au-dessus" des objets du domaine. Bien sûr, vous devrez vous assurer que le code d'initialisation est appelé avant que les objets de domaine puissent être créés. Il devrait probablement lancer une exception s'il n'est pas initialisé, donc vous pouvez au moins l'attraper facilement.

Ainsi, le constructeur devient

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

Et quelque part peu après que vous initialisez NHibernate vous appelleriez:

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

Votre réponse serait injection de dépendance.

Utilisez-le et ne pas poluer le modèle avec la configuration. Si vous devez créer un paiement avec requis Montant et monnaie - il suffit de faire exactement cela:

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

Ne présumez pas la devise par défaut.

ou au pire fin, vous pouvez ajouter 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(); 
} 

afin que vous puissiez INJECTER (en utilisant Windsot, unité ou autre) que fournisseur de devise par défaut dans la méthode où vous instancier Paiement:

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

-1 de moi - Je crois qu'il existe un autre moyen d'obtenir des informations sur les devises sans recourir à la persistance ou à l'injection de dépendances. – duffymo

2

Je ne vois pas pourquoi cela doit avoir quelque chose à voir avec la persistance à tout. Si j'écrivais ceci en Java, j'obtiendrais la devise par défaut des paramètres régionaux pour l'application.

This SO question me dit que CultureInfo est l'équivalent C#. Peut-être que vous devriez essayer cela dans votre conception, et laisser des chaînes comme "JPY" et la persistance hors de lui.

+0

C'est une bonne idée ... pour le cas de la monnaie mais cela ne règle pas vraiment le problème de base. Tout ce que vous faites est de déplacer la persistence d'une base de données vers un référentiel de registre OS. Donc, si, par exemple, vous aviez migré vers Unix, l'environnement local serait différent et donc je devrais changer mon modèle de domaine ... – thrag

+0

Passer à Unix? Je suppose que tu penses à Mono. Je suis plus familier avec Java, donc j'ai supposé - peut-être incorrectement - que Locale/Culture serait quelque chose que j'obtiendrais des en-têtes HTTP définis par le navigateur du client si j'écrivais une application web. – duffymo

Questions connexes