Alik Levin's

Clarity, Technology, and Solving Problems | PracticeThis.com 

May, 2010

  • Alik Levin's

    Solution Architecture For The Masses. Step 2: Design Your Entities & Business Components

    • 0 Comments
     Alik Levin   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]:

    • Nouns == Classes
    • Verbs == Methods, Services, etc

    Looks like old plain OOP, eh?

    I have two user stories [scenarios]:

      1. User transfers money from one account to another.
      2. User searches for transactions he performed.

    Identifying Aggregates and Repositories

    How 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:

    • AccountInfo
    • TransactionInfo

    and these repositories [I could call it xxxRepository but I love xxxServices better ;)]:

    • AccountServices
    • TransactionServices

    Defining Entities

    I 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:

    • If you must implement complex business rules.
    • If you are using the ADO.NET Entity Framework or ADO.NET LINQ.
    • If you are working with large volumes of data.
    • If you want to maximize performance when passing data across AppDomain, process, and physical boundaries. Custom objects can be serialized using a binary format, which is much faster than XML formats…”

    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:

    “…Domain Value Objects are lightweight objects that represent domain entities, but do not contain business rules. These objects are sometimes referred to Data Transfer Objects (DTO), which is a design pattern used to package multiple data structures into a single structure for transfer across AppDomain, process, and physical boundaries. With a domain value object, the main goal is to define business entities that represent entities in the business domain while maintaining the relationship between those entities…”

    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 Services

    Expand 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 Test

    I 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:

    image

    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:

    image

    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

  • Alik Levin's

    Solution Architecture For The Masses. Step 1: Structure Your Solution

    • 0 Comments

     Alik Levin    This is a first post in series “Solution Architecture for the Masses”. I decided to take p&p’s Application Architecture Guide (2nd Edition) for a test drive.

    This post follows the guidelines described in the resources outlined in the Quick Resource Box on the right or at least the way I understood it.

    Quick Resource Box

    The rest of the post is an explanation of how I partitioned my Visual Studio solution according to the guidelines.

    Layers Mapped to Visual Studio Solution

    From the How To - Structure Your Application:

    Layers represent a logical grouping of components into different areas of concern. For example, business logic represents an area of concern that should be grouped into a layer. This is probably the most important decisions you will make during the initial design phase of your application. …

    From Application Architecture Guide - Chapter 9 - Layers and Tiers:

    image

    Red square that I have added in the figure above should map to the solution in Visual Studio. Right click on the solution node in Solution Explorer –>Add –> New Solution Folder to create the structure similar to below:

    image

    I have added numbers to the names so that VS sorts it top down like in the conceptual diagram. It helps navigating the solution.

    User Interface [UI] Folder

    The UI Solution folder holds Web App and Silverlight applications – notice there might be several Silverlight applications that will be used for different Use Cases [UC] for the same web app.

    image

    Service Interface [SI] Folder

    Service Interface folder holds WCF projects that will be consumed by remote clients or by our own Silverlight applications – notice it has svc file, interfaces, and interfaces implementations (servicecontract/operationcontract). It does not contain datacontract which is factored out into separate project (later on this one):

    image

    Entities Folder

    Entities folder holds Entities project. It is my data model that flows through layers. I have factored it into separate project so I will be able to reference it from different projects as entities usually flow through all layers and sometimes tiers.

    image

    Business Services Folder

    Business services folder holds Business Services objects that will be activated by WCF and ASPX on the server side. It is a bunch of Use Case oriented classes with static methods that should access DAL when processing entities.

    image

    Data Access Folder

    Data Access folder holds project for Data Access Layer [DAL] that’s responsible for accessing the entities in the data sources and downstream services. For each entity I have a set of CRUD related operations. It also contains data access helper classes:

    image

    Crosscutting Folder

    Crosscutting folder contains non-functional aspects such monitoring, exception handling, security, etc:

    image

    I am ready to expand each folder and add the implementation to it. Business Entities and Business Services are next.

    Related Books
Page 3 of 3 (8 items) 123