[. NET domain driven design Combat Series] topic two: Building an online bookstore with a service-oriented architecture based on domain-driven design

Source: Internet
Author: User
Tags net domain

Original address: http://www.cnblogs.com/zhili/p/OnlineStorewithDDD.html

First, preface

In the previous topic I, I have already introduced my intention to write this series of articles. Since the DDD framework in Dax.net and the Byteart retail case do not take a step-by-step analysis of their formative process, they present the entire DDD implementation case to us, which may be very confusing for some friends who have just touched on the domain-driven design and feel that domain-driven design is difficult and complex, Because the study to digest a whole case of knowledge, this is a lot of people can not digest on the back, do not continue to study, so it is not conducive to the promotion of DDD. However, this series can be said to be the first contact field-driven design friends of the Gospel, this series will be combined with the idea of domain-driven design to build an online bookstore, so that we learn that DDD is no longer boring and can see a DDD case formation process. Finally, after the DDD case is completed, a domain-driven framework is drawn from it, so that you can see the formation of a DDD framework, so that you don't digest the whole framework and case knowledge at once, but step-by-step. Next, the topic will introduce: building an online bookstore with the SOA architecture of domain-driven design, which does not complete all the pages of the online bookstore and covers all the content in DDD, but only part of it, and the following topics will be perfected in the online bookstore of the topic, Complete the project by introducing the content and refactoring of DDD in one step.

Second, DDD layered architecture

Conceptually, the domain-driven design architecture is divided into four layers, namely: infrastructure, domain, application and presentation.

    • Infrastructure layer: This layer is designed to support a wide range of common technical frameworks for other tiers. Like some configuration file processing, cache processing, transaction processing and so on can be put here.
    • Domain layer: In short, the domain objects (including entities, value objects), Domain Services, etc. that are involved in the business. This layer is the so-called domain model, the domain-driven design advocates the rich domain model, the rich domain model refers to: As far as possible the business logic to belong to its domain object. The domain model in the previous three-tier architecture is an anemic domain model, because the domain model in layer three contains only business attributes, not any business logic. The online bookstore domain model for this topic does not yet contain any business logic and will be perfected in the later stages.

   An entity can be considered a table that corresponds to a database, whereas a value object is generally defined in an entity class.

    • Application layer: This layer does not contain any domain logic, it is mainly used to coordinate the task, it constructs the expression layer and the domain layer bridge. The SOA architecture is implemented at that level.
    • Presentation layer: Refers to the user interface, such as the ASP. NET MVC Web site, WPF, WinForm, and console. It is used primarily to show content to users.

Below is a graph to show the hierarchical architecture of DDD:

This series introduces the field-driven design practice, it is less natural to achieve the domain-driven design layered architecture, the above simple introduction of domain-driven hierarchical architecture, the next will be detailed in the online bookstore how to achieve the level.

Third, the realization of the online bookstore domain model layer

To build a project in the field of application-driven design, the first step is to understand the requirements, understand the business logic of the project, understand the business logic, and then abstract the business logic into domain objects, where the domain objects are placed in the domain model layer. The online bookstore of the presentation mainly completed the pages involved in the product, including the product homepage, details of individual items, etc. So the domain entities involved are 2, one is commodity, the other is category, because in the Product home page, you need to show the category of all items. Before giving an implementation of the domain object, here are a few concepts to be covered in the domain layer.

    • Aggregate root: The aggregate root is also an entity, but unlike an entity, an aggregate root is a system boundary object that consists of entities and value objects. For instance, for example, orders and order items, according to business logic, we need to track the status of orders and order items, so we design them as entities, but only the order is the aggregate root object, and the order item is not, because the order item is only meaningful in the order, meaning: the user cannot see the order item directly, Instead, the order item is queried before the order. So the aggregation root can be understood as the object that the user directly operates. Here the commodity and class classes are an aggregate root.

Based on the interface-oriented programming principle, we should define an entity interface and aggregate root interface in the domain model, and because the aggregation root is also an entity, the aggregation root interface inherits from the entity interface, and the commodity and class classes are aggregate roots, so they all implement the aggregation root interface. Implement the entity interface if a class like an order item is simply an entity that is not an aggregate root. With the above analysis, the implementation of the domain model layer will naturally come out, the following is the specific implementation of the domain object:

Domain entity Interface Public    interface ientity    {        //the current domain entity's globally unique identity        Guid Id {get;}    }
An aggregate root interface, an object that inherits from the interface, is an externally unique operation of the object public    interface iaggregateroot:ientity    {    }
Commodity public class    Product:aggregateroot    {public        string Name {get; set;}        public string Description {get; set;}        Public decimal UnitPrice {get; set;}        public string ImageUrl {get; set;}        public bool isnew{get; set;}        public override string ToString ()        {            return Name;        }    }
Category class public class    Category:aggregateroot    {public        string Name {get; set;}        public string Description {get; set;}        public override string ToString ()        {            return this. Name;        }    }

In addition, the domain layer needs to define the storage interface in addition to the domain object, while the storage layer is the realization of the warehousing interface. Warehousing can be understood as maintaining a collection of aggregate roots in memory, and the aggregate root cannot always exist in memory and is persisted into the data when it is inactive. The task of the storage layer is to persist the aggregation of the root object to the data or to query the stored object from the database to recreate the Realm object.

The storage layer has several concepts that need to be clear:

    The object that is stored in the
    1. warehouse must be the aggregation root, because the domain model is divided by the concept of the aggregation root, which is a boundary of the object we manipulate. So we're all working on an aggregate root, and there's no manipulation of value objects within the aggregation. Therefore, the storage is only for the aggregation root design.
    2. because warehousing is designed for aggregate roots only, an aggregation root needs to implement a warehousing.
    3. instead of simply understanding warehousing as a DAO, warehousing is part of the domain model and represents a part of the domain model providing interfaces to the outside world, while DAO is the representation of the interface that the database provides to the upper layer. One is for the domain model and the other for the database. The focus is not the same. The
    4. warehousing is divided into definition and implementation sections, which define the interfaces for warehousing in the domain model, and implement specific warehousing at the infrastructure level . The reason for this is that because the implementation behind warehousing is all about dealing with databases, we do not want customers (such as the application layer) to focus on the issue of how to get data from the database, because doing so will cause the customer (application layer) code to be confusing and will likely ignore the existence of the domain model. So we need to provide a simple and straightforward interface for the customer to use, to make sure that the customer can get the domain object in the simplest way, so that it can focus on coordinating the domain object to complete the business logic without being disturbed by any data access code. This approach to isolating package changes through an interface is actually common. Because the client is facing the abstract interface is not a specific implementation, so we can at any time replace the real implementation of warehousing, which is very helpful for us to do unit testing. In the case of this topic, we carried out the implementation of the storage layer separately from the infrastructure layer, as a separate layer exists. This is why there is no storage layer defined in the DDD hierarchy, and there is a storage layer implementation in the case of this topic.
    5. Warehousing often uses the protocol pattern (specification pattern) when designing query interfaces. This is not given in the case of this topic, which will be added later in the topic.
    6. Warehousing is generally not responsible for transaction processing, the general transaction will be handed over to the "unit of work" to deal with, the same topic also does not involve the implementation of the work unit, which will continue to be improved in the following topic. Here is a list of the topics that can be clearly defined in the following sections, without being unfounded.

After the introduction of warehousing, the next step in the domain layer to define the warehousing interface, because this topic involves 2 aggregation root, then naturally need to implement 2 storage interfaces. Based on the interface-oriented programming principles, we have implemented these 2 warehousing interfaces with a common interface: IRepository interface. In addition, the warehousing interface also needs to define a warehouse up and down interface, because there is a Dbcontex class in the Entity Framework, so we need to define a EntityFramework context object to wrap the Dbcontex. It is also natural to have a warehousing context interface. Through the above analysis, the implementation of the warehousing interface is also a glance.

Warehousing interface Public    interface irepository<taggregateroot>         where Taggregateroot:class, Iaggregateroot    {        void Add (Taggregateroot aggregateroot);        Ienumerable<taggregateroot> GetAll ();        The aggregate root        taggregateroot Getbykey (Guid key) is read from the repository based on the ID value of the aggregation root;    }
Public interface iproductrepository:irepository<product>    {        ienumerable<product> getnewproducts (int count = 0);    }
Public interface iproductrepository:irepository<product>    {        ienumerable<product> getnewproducts (int count = 0);    }
Warehousing Context Interface Public    interface Irepositorycontext    {    }

So we have completed the construction of the domain layer, next, we need to define the domain layer of the storage interface is implemented. I have made a separate layer for the implementation of the warehousing interface, and of course you can put it in the Repositories folder in the infrastructure layer. But I think a lot of people are just carrying it out. I am also here directly as a layer.

Iv. realization of repository (storage) layer in online bookstore

After the storage interface is defined, the next step is to implement these interfaces in the storage layer to complete the serialization of domain objects. The first is the realization of product warehousing:

View Code

Next is the implementation of the category warehousing:

View Code

In addition to implementing the implementation based on the EF warehousing, we also wanted to implement the implementation based on MongoDB warehousing, so we created a entityframework folder in the storage layer. and defines a ientityframeworkrepositorycontext interface to inherit from the Irepositorycontext interface, because the persisted data in EF is mainly done by the DbContext object, in order to have its own framework model, I have defined the onlinestoredbcontext here to inherit the DbContext, thereby using the Onlinestoredbcontext to wrap the dbcontext. After the above analysis, the next step for the implementation is also at a glance. The first is the implementation of the Onlinestoredbcontext class:

public sealed class Onlinestoredbcontext:dbcontext    {        #region Ctor public        onlinestoredbcontext ()            : Base ("Onlinestore")        {this            . Configuration.autodetectchangesenabled = true;            This. Configuration.lazyloadingenabled = true;        }        #endregion         #region Public Properties public        dbset<product> products         {             get {return this. Set<product> (); }        } public        dbset<category> Categories        {            get {return this. Set<category> (); }        }        //will continue to add attributes for each aggregate root to define a Dbset property        //...        #endregion    }

The next step is the definition of the Ientityframeworkrepositorycontext interface and its implementation. The specific code looks like this:

Public interface Ientityframeworkrepositorycontext:irepositorycontext    {        #region Properties        Onlinestoredbcontext Dbcontex {get;}        #endregion     }
public class Entityframeworkrepositorycontext:ientityframeworkrepositorycontext    {        // Refer to our defined Onlinestoredbcontext class object public        onlinestoredbcontext Dbcontex        {            get {return new Onlinestoredbcontext (); }        }    }

In this way, our storage layer is finished. The next step is the implementation of the application layer.

Implementation of application layer in online bookstore

The application layer is implemented using service-oriented architecture and implemented by Microsoft service-oriented implementation of WCF. The entire architecture of the online bookstore follows the hierarchical architecture of the domain-driven design, where the user operates through the UI layer (the Web page is implemented here), and the UI layer invokes the application layer to distribute the service, persisting and rebuilding the domain object by invoking the warehousing implementation in the infrastructure layer. Here the application layer is mainly implemented by WCF, which refers to the warehousing interface. In terms of service, we need to define the service contract first, here I put the definition of service contract in a service contract layer, of course, you can also create a service contract folder in the application layer. First, look at the definition of service contract:

View Code

Next is the implementation of the service contract, the implementation of the service contract I put in the application layer, the specific implementation code is as follows:

View Code

The end is to create a WCF service to invoke the service contract implementation. To create a WCF service file with the suffix. svc, the specific implementation of the WCF service is as follows:

Commodity WCF Service public    class Productservice:iproductservice    {        //reference Commodity service Interface        private readonly Iproductservice _productservice;        Public Productservice ()        {            _productservice = servicelocator.instance.getservice<iproductservice> ();        } Public        ienumerable<product> getproducts ()        {            return _productservice.getproducts ();        }        Public ienumerable<product> getnewproducts (int count)        {            return _productservice.getnewproducts ( count);        }        Public ienumerable<category> getcategories ()        {            return _productservice.getcategories ();        }        Public Product Getproductbyid (Guid id)        {            return _productservice.getproductbyid (ID);        }    }

Here we have completed the application level to the service architecture implementation. From the implementation of the WCF service of the commodity we can see that we have a servicelocator class. The implementation of this class uses the service locator mode, the introduction of this mode can refer to the Dax.net Service locator mode. The purpose of this class is to invoke the specific instance, simply to define the implementation of the specific service interface through the service interface, and return the implementation to the caller. This class I put here in the infrastructure layer to achieve. Currently the infrastructure layer only implements this class, and later continues to add additional features, such as support for caching features.

In addition, the unity dependent injection container is used here to inject the interface. The main configuration files are as follows:

View CodeVI. implementation of the infrastructure layer

The infrastructure layer only includes the implementation of the service locator in this topic, and later continues to add support for other features, as the Servicelocator class is implemented as follows:

View CodeVii. implementation of the UI layer

Depending on the domain-driven hierarchical architecture, the next step is to implement the UI layer, where the implementation of the UI layer is implemented using ASP. The UI layer mainly includes the implementation of the Product home page, and the implementation of the detailed product, plus some additional page implementations, for example, about the page, contact us page and so on. About the implementation of the UI layer, here do not post code implementation, you can in the last source link to download their own view.

Viii. overall architecture of the system

After all the steps above, the construction of the online bookstore in this topic is basically completed, and then we will look at the overall structure of the online bookstore (the architecture diagram directly draws on Dax.net's diagram, as this series is also the anatomy of its Byteart retail project):

Finally, a schematic diagram of the entire solution is attached:

Nine, online bookstore operation effect

After the realization, people are not eager to see the effect of online bookstore operation? The following for everyone to announce, the current online bookstore mainly includes 2 pages, one is the product home page display and product details display. First look at the product home page look like it:

The details page of the book:

X. SUMMARY

Here, the content of this topic is finished, this topic mainly introduces the domain-driven design of the hierarchical architecture and service-oriented architecture. Then combine them in the online bookstore to conduct practical exercises. In the following topics I will continue to refine the project to form a complete DDD case. In the following topics will apply to the implementation of warehousing protocol model, before application, I will first write a topic to introduce the statute model as a preparatory work.

GitHub Open Source Address: Https://github.com/lizhi5753186/OnlineStore.

[. NET domain driven design Combat Series] topic two: Building an online bookstore with a service-oriented architecture based on domain-driven design

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.