Solution Architecture For The Masses. Step 2: Design Your Entities & Business Components
After I have structured my solution in Visual Studio I decided to first design my Business Entities and Business Components that will act upon the Entities. I like the idea of focusing on domain first – something that Domain Driven Design is all about. | Quick Resource Box |
Chapter 4: Designing Your Architecture guides to “Use stories from multiple perspectives to help expose the key scenarios for your system” and in the Domain Driven Design presentation there is a good guidance how to use the stories to model the language used by business analysis [domain experts]:
Looks like old plain OOP, eh? I have two user stories [scenarios]:
Identifying Aggregates and RepositoriesHow To: Domain Driven Design guides how to use Entity Framework to implement Domain Driven Design. I will stick with something simpler than that. It also shows how to derive Aggregates [Nouns/Classes/Entities] and Repositories [Verbs/Methods/Services]. For my scenarios I’ll stick with these Entities:
and these repositories [I could call it xxxRepository but I love xxxServices better ;)]:
Defining EntitiesI am a big fan implementing entities based on custom objects [vs. DataSets, XML, or other options]. How To: Design Business Entities offers fantastic comparison between different options. The following only makes me more comfortable to stick with custom objects [performance is my favorite, of course]: “…Consider using custom objects:
Expand Entity folder in Visual Studio. Expand Entities project. Add a class and name it AccountInfo. It’s behaviorless class. Its behavior [methods or services] will be defined in separate project in Business Services folder as AccountServices class with static methods. This separation fosters service oriented design regardless of actual final physical deployment. Same story with Transaction. This is how the guide explains it:
I mark entity classes with DataContract and DataMember attributes as I expect I might be using it for my services too that would be implemented as WCF services. AccountInfo entity should look similar to the following. namespace Entities { [DataContract] public class AccountInfo { private string m_id = string.Empty; private string m_ownerId = string.Empty; private string m_currency = string.Empty; private double m_balance = double.NaN; [DataMember] public string Id { get { return m_id; } set { m_id = value; } } [DataMember] public string OwnerId { get { return m_ownerId; } set { m_ownerId = value; } } [DataMember] public string Currency { get { return m_currency; } set { m_currency = value; } } [DataMember] public double Balance { get { return m_balance; } set { m_balance = value; } } } } The TransactionInfo class looks similar to the following(consider adding [DataContract] and [DataMember] if you are planning to use it in WCF. Consider adding it anyway, if you do not use it in WCF in the end – it won’t hurt anybody anyway): public class TransactionInfo { private string m_transactionId = string.Empty; private string m_transactionAccount = string.Empty; private string m_transactoinAction = string.Empty; private double m_transactionAmount = double.NaN; private DateTime m_transactionDateTime = DateTime.MaxValue; public DateTime TransactionDateTime { get { return m_transactionDateTime; } set { m_transactionDateTime = value; } } public string TransactionId { get { return m_transactionId; } set { m_transactionId = value; } } public string TransactionAccount { get { return m_transactionAccount; } set { m_transactionAccount = value; } } public string TransactoinAction { get { return m_transactoinAction; } set { m_transactoinAction = value; } } public double TransactionAmount { get { return m_transactionAmount; } set { m_transactionAmount = value; } } } Defining Business ServicesExpand Business Services folder in Visual Studio. Expand BusinessServices project. Add two classes AccountServices and TransactionServices. Also, add reference to Entities project. Basically, these classes define behavior for the entities. I’ll start with AccountServices. I will be using it with my first user story which goes along the line “User transfers money from one account to another”. To transfer from one account to another I’d first present the list of accounts – that’s where it’ll be useful. public class AccountServices { public static List<AccountInfo> GetCurrentUserAccounts() { List<AccountInfo> result = null; //MOCKING UP THE RETURN RESULT //IT WILL BE IMPLMENTED FURTHER VIA DAL result = new List<AccountInfo> { new AccountInfo("ac1","ownr1", "USD", 1001), new AccountInfo("ac2","ownr2", "USD", 1002), new AccountInfo("ac3","ownr3", "USD", 1003), new AccountInfo("ac4","ownr4", "USD", 1004), new AccountInfo("ac5","ownr5", "USD", 1005), new AccountInfo("ac6","ownr6", "USD", 1006), }; return result; } } Test Your Implementation Using Unit TestI am ready to test my simple design and implementation. I will do it using adding a unit test to my solution. To do so right click on GetCurrentUserAccounts method and then “Create Unit Tests…”. Name the new project BusinessServicesTests in ‘Output project:” field. Click OK. Optionally drag the project under Business Services folder. Implement simple Unit test under GetCurrentUserAccountsTest. The result should look as follows:
Now lets run the Unit Test to verify the implementation. To do so choose Test in the menu->Windows->Test View. You should see Test View window and the Unit Test you have just created in it. Right click on it and choose “Run Selection”. The outcome should be present in “Test Results” window below:
Seems like it works. I can go off and implement the rest of the services this way so I could use it in my Web UI which is the next step. Related Books |