0

I have Person aggregate, which is root aggregate

public class Person 
{
    private int id;
    private readonly PersonID personID;

    private readonly string email;
    private readonly string firstName;
    private readonly string lastName;

    private readonly string username;
    private readonly string password;
    private readonly Address BillingAddress;
}

public class Currency : IValueObject<Currency>
{
    private string name;
    private string currencyCode;
    private decimal rate;
    private string displayLocale;
    private string customFormatting;
    private int displayOrder;
    private bool primaryExchangeRateCurrency;
    private bool primaryStoreCurrency;

    //<summary>
    //Gets or a value indicating whether the currency is primary exchange rate currency
    //</summary>

    public bool IsPrimaryExchangeRateCurrency
    {
       get
       {
           return primaryExchangeRateCurrency;
       }
    }

   /// <summary>
    /// Gets or a value indicating whether the currency is primary store currency
    /// </summary>

    public bool IsPrimaryStoreCurrency
    {
         get
         {
                return primaryStoreCurrency;
         }
    }
}

and Currency class, which is to be referenced in Person class.

So now if a Person entity is created , we need to associate it a currency too.But among all Currencies created, i want to know which is the default primary store currency. I don't want to know it through Person because it contains only single currency. I want to get a currency which is PrimaryStoreCurrency from all created currencies of persons.

I want to bind currency in drop down so that user can select its currency from dropdown and register in our system.

So, do i create Currency as seperate aggregate ?

kamal
  • 739
  • 1
  • 9
  • 21

2 Answers2

5

If you mean by Currency the currency definition in the application like USD, EGP, EUR, .. and so on, it should be reusable entity. If you mean the value of money amounts, like 1000 USD, it's a value object encapsulating the amount and the currency type.

M.Sameer
  • 3,072
  • 1
  • 24
  • 37
  • So you mean the Currency definition I was talking about. It should be separate aggregate. I also have an advice, instead of making bool property to specify if it's the default for the store and another to determine it's the primary exchange rate currency, I would recommend you make two static properties of type Currency to reference the two default and primary currencies. It will make it easier to find them instead of searching amount the currencies for the ones with true values (if I understood correctly that it will be one primary and one default currency among all). – M.Sameer Apr 16 '11 at 22:56
  • How do i bind to dropdown, so that user selects from drop down and register itself. – kamal Apr 16 '11 at 23:11
  • Agree with static properties, but how do i get primary currency to assign them in static properties. Do i have to query all person's currency and get the primary currency and then assign in static properties. – kamal Apr 16 '11 at 23:15
  • You will not need to search if you do not store it with the currency. The good practice according to my experience is to store it with system options. It may be in .config file or a special DB table for options. I do not understand what you mean by the drop down question. – M.Sameer Apr 16 '11 at 23:21
  • i want to give drop down to user so that he can select his currency, say dollar or pound or dinar from drop down . Do i create separate xml file for it ? – kamal Apr 16 '11 at 23:30
  • If the store is all XML and you do not use DB then yes you may store all currencies in one XML file. If you have DB then all currencies will be in one table. You will just need to query the store (XML or DB) and bind the drop down to the result list of objects. When the user makes a selection, get the selected object and assign it to the currency property in the person which should be stored as the currency code back in the store. Do I understand you correctly ? – M.Sameer Apr 16 '11 at 23:38
  • Suppose my currency table is blank for the first time, how can i bind dropdown for currencies. – kamal Apr 16 '11 at 23:43
  • It will appear empty and the currency of the person will be null. The user will then have to save the person and go define some currency and come back to assign one for the person. The business logic should assume persons with null currency as having the default system currency. The default system currency should be defined by the admin or who has permission to define the currencies. – M.Sameer Apr 16 '11 at 23:53
  • If admin defines default currencies then he has to create default persons too unecessarily ? – kamal Apr 16 '11 at 23:59
  • No he does not. Persons depend on currencies and not vice versa. – M.Sameer Apr 17 '11 at 00:00
4

The following quote is from Eric Evans where he describes what a Value Object is:

An object that represents a descriptive aspect of the domain with no conceptual identity is called a VALUE OBJECT. VALUE OBJECTS are instantiated to represent elements of the design that we care about only for what they are, not who or which they are.

Another reference on this is the MSDN article on Domain Driven Design written by Dave Laribee where he says:

Value objects are descriptors or properties important in the domain you are modeling. Unlike entities, they do not have an identity; they simply describe the things that do have identities. Are you changing an entity called "Thirty-Five Dollars" or are you incrementing the balance of an account?

Using these two references I'd say that Currency should be a Value Object and not an entity. Currency doesn't have any sort of identity through time - it is descriptive property of the person entity - the currency that they prefer to be billed in I guess.

And there is no problem at all in using the same Value Object in two different aggregates.

Another nice post that may help you was written by Jimmy Bogard


After your additional information:

I would still say that Currency is best modelled as a Value Object - it still appears to be immutable.

When you load up your Person aggregate you require part of that query to be loading the Currency Value Object which is the primary store currency.

For updating the currency in the database (changing which is the primary store currency for example) or for listing the available currencies, your do not need to go through an aggregate, aggregates are not mandatory for all data access - they only serve for coordinating the relationships between entities in a managable way.

David Hall
  • 32,624
  • 10
  • 90
  • 127
  • 1
    The currency mentioned is not immutable. If it's a value object then you will get different objects for two persons having the same currency which is wrong. Money amounts are value objects but Currency types like this are entities. – M.Sameer Apr 16 '11 at 23:25
  • It should be vo, because change in one person's currency should not effect other's. – kamal Apr 16 '11 at 23:32
  • Hey david can u explain bit more in your line "When you load up your Person aggregate you require part of that query to be loading the Currency Value Object which is the primary store currency." . I cannot load any other currency in person. In payment aggrgate i want to assign primary currency to a property. – kamal Apr 16 '11 at 23:35
  • @kamal - that was simply me trying to interpret your business rules. What I meant was that the person aggregate is responsible for populating itself with the right currency, and so is the payment aggregate. – David Hall Apr 16 '11 at 23:44
  • @kamal if you change person currency you do not change the currency definition. You just change the reference to specific currency. – M.Sameer Apr 16 '11 at 23:56
  • @DAVID, See Payment entity, has reference of Person. Since payment has only reference of associated person. How do i get a Currency which is primarycurrency ? – kamal Apr 16 '11 at 23:56