zoukankan      html  css  js  c++  java
  • 【转】A brief overview of Ncqrs

    What is CQRS / Ncqrs?
    CQRS is an evolutionary step in Domain-Driven Design (DDD). Ncqrs is an open-source implementation for.NET.


    Links: CQRS
    Wikipedia's entry for Command-query separation
    Udi Dahan's explanation of Command-Query Responsibility Segregation.
    Greg Young's video presentation CQRS and Event Sourcing - the Business Perspective.

    Links: Ncqrs 
    For information on Ncqrs, see ncqrs.org.
    To try out the Ncqrs walkthrough tutorial, go here.


    The goal of this blog post is to compare Ncqrs with regular Domain-Driven Design (particularly when used with Remote Facade), and to examine and understand the processes described in the Ncqrs tutorial.

    In regular Domain-Driven Design across a web service boundary, both inputs (commands) and outputs (queries) share the same RemoteFacade and Application Service Layer, as shown in Fig. 1. 

    Fig.1  Regular DDD with Remote Facade
    CQRS
    In Command-Query Responsibility Segregation Pattern, inputs (commands) and outputs (queries) are separated and treated very differently. As Greg Young points out in the video presentation (above), using the RemoteFacade/DDD architecture for simple queries leads to an immense amount of busy work (mapping from the domain to DTOs, etc), when the real purpose of the domain model is to implement behavior/business logic--which only occurs based on input (commands).

    Therefore:
    CQRS in 50 words or less
    1) Keep DDD and the domain model, but call it only from commands. 
    2) Add a new feature: TRACK each command as event history
    3) For queries, SKIP the domain model. Do queries quick, dirty and denormalized.

    How does Ncqrs implement this approach? Let's walk through the journey that a command follows, based on their tutorial. I've created the following diagram as a guide:

    1. In your backend behind the RemoteFacade, create a custom command class such as PostNewTweetCommand (which inherits from Ncqrs.Commanding.CommandBase).
    2. For any input values you wish to pass to the domain model, create properties in the custom command class. For example: 

      public string Message { get; set; }
      public string Who { get; set; }

    3. In your WCF web service, create a method which accepts PostNewTweetCommand as input parameter.
    4. In your client, create the WCF proxy.
    5. In your client, create an action which instantiates PostNewTweetCommand, sets its property values, and passes it to the web service method.
    6. In your WCF web service method, get an ICommandService instance (from Ncqrs.Commanding.ServiceModel) and use it to execute the incoming PostNewTweetCommand input parameter.
    7. Create a PostNewTweetCommandExecutor class (which inherits from CommandExecutorBase<PostNewTweetCommand>) that--by convention--listens for executed instances of PostNewTweetCommand
    8. Have the command executor execute the incoming command, in the context of an IUnitOfWork, against a domain model class (typically an aggregate root)
    9. In the domain model class (eg. Tweet.cs), every public action (such as instantiation, or a method call) creates a domain event to process the incoming command, map over its input values, and then call ApplyEvent().
    10. In this case, the contextual IUnitOfWork writes the event (TweetPostedEvent) to the event store.
    11. As part of setting up the WCF service, three services have been bootstrapped in service of CQRS goals: 

      • ICommandService - already mentioned, this processes the incoming commands, and uses convention to call the correct command executor
      • IEventStore - this processes each event transaction and writes it out to a separate data store (in the tutorial example, a SQL Server database)
      • IEventBus - listens for new events, and for each one, makes a call out to the final piece of the ncqrs puzzle (described next)
    12. The event bus alerts classes (again, by convention) which inherit from IDenormalizer where T is the particular event that has been saved.
    13. The implementing class (in this case, TweetIndexItemDenormalizer is so named based on a new, separate database whose purpose is to store, simple, denormalized, read data.
    14. The TweetIndexItemDenormalizer class implements a Handle method, which takes the TweetPostedEvent as input param, and write the values stored in that event to the denormalized data table.
    15. Finally, the client can now (very simply) access data from this denormalized table (eg. as a simple Linq to SQL call to get a list of matching values.)
  • 相关阅读:
    github.com/dotnet/orleans
    C#开源
    Windows Server 2016正式版14393英文版ISO镜像下载:_X64FRE_ZH-CN.ISO
    Windows Server 2016
    功能更新到 Windows 10 企业版, 版本 1607
    Load Audio or Vedio files
    Socket.Available 属性
    CaptureManagerSDK
    Net.Sockets
    Solid Edge如何制作装配体的剖视图
  • 原文地址:https://www.cnblogs.com/NickYao/p/1853529.html
Copyright © 2011-2022 走看看