Posted by John Sonmez on Jun 20, 2010 in
- Dotnet,
- Silver Light |
View Original Article
If you have ever written code that is going to be used as an API for other programmers, you may start to think about writing code in a different viewpoint from what you normally do.
Most of us write code for the purpose of achieving a goal. If we practice writing elegant code, we are conscious of making that code as readable and terse as possible.
Seldom do we think about the use of our code from an API standpoint.
There is a subtle difference between designing your code in a way that will make it easier for someone else to maintain, and designing your code in a way that will make it easier for someone else to use.
Intellisenselessness
How often are you working against some API and you type a method name you want to use only to have intellisense present you with 5 overloads for the method all with several different parameters choices?
Which one do you use? It is hard to be sure, you end up having to read through the long lists of parameters to figure out what method you should call and what parameters you should pass it.
Wouldn’t it be better if you were presented with what the method does in the method name rather than guessing what it does in the parameter list? Something like this?
Perspective
From the perspective of the person writing the Login method(s), overloads probably seem like the most efficient and correct way to implement the multiple ways the method can be called.
From the perspective of the person using the Login method(s), additional methods are much preferred, because they are easier to understand and know what you are looking for.
Try to think from the perspective of someone using your code when writing your code.
Extract boolean parameter to two methods
I want to take a look at a very specific example that can be of great benefit to the readability and use of your code.
Take a look at this code below.
1: public void Login()
2: {
3:
4: }
5:
6: public void Login(bool rememberMe)
7: {
8:
9: }
Seems like a fine overload of a Login method. I have written code just like this, you probably have also.
Unfortunately, by adding this overload, we have added some complexity to our API, because now the user of that code has to see that there is an additional overload that take a bool parameter called rememberMe.
Consider this longer alternative.
1: public void LoginRememberMe()
2: {
3:
4: }
5:
6: public void LoginDoNotRememberMe()
7: {
8:
9: }
Instead of overloading Login and making the user have to decide which overload to call and pass in a parameter, we have elected to create two differently named methods which take 0 parameters and clearly state what they are going to do.
I’m not saying you should never write overloads, but anytime you see an overload in your code base, you should stop and think if it would be more clear to make that overloaded method into two different methods that can eliminate one or more of the parameters.
Any time you are restricting the number of choices someone using your code has to make, you are making that code simpler to use.
If you don’t believe me, consider why the iPhone has only one button.
As always, you can subscribe to this RSS feed to follow my posts on elegant code. Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week. Also, you can follow me on twitter here.
Tags: - Virtualization, Application Packaging, Architecture, Craftsmanship
Posted by John Sonmez on Jun 20, 2010 in
- Dotnet,
- Silver Light |
View Original Article
If you have ever written code that is going to be used as an API for other programmers, you may start to think about writing code in a different viewpoint from what you normally do.
Most of us write code for the purpose of achieving a goal. If we practice writing elegant code, we are conscious of making that code as readable and terse as possible.
Seldom do we think about the use of our code from an API standpoint.
There is a subtle difference between designing your code in a way that will make it easier for someone else to maintain, and designing your code in a way that will make it easier for someone else to use.
Intellisenselessness
How often are you working against some API and you type a method name you want to use only to have intellisense present you with 5 overloads for the method all with several different parameters choices?
Which one do you use? It is hard to be sure, you end up having to read through the long lists of parameters to figure out what method you should call and what parameters you should pass it.
Wouldn’t it be better if you were presented with what the method does in the method name rather than guessing what it does in the parameter list? Something like this?
Perspective
From the perspective of the person writing the Login method(s), overloads probably seem like the most efficient and correct way to implement the multiple ways the method can be called.
From the perspective of the person using the Login method(s), additional methods are much preferred, because they are easier to understand and know what you are looking for.
Try to think from the perspective of someone using your code when writing your code.
Extract boolean parameter to two methods
I want to take a look at a very specific example that can be of great benefit to the readability and use of your code.
Take a look at this code below.
1: public void Login()
2: {
3:
4: }
5:
6: public void Login(bool rememberMe)
7: {
8:
9: }
Seems like a fine overload of a Login method. I have written code just like this, you probably have also.
Unfortunately, by adding this overload, we have added some complexity to our API, because now the user of that code has to see that there is an additional overload that take a bool parameter called rememberMe.
Consider this longer alternative.
1: public void LoginRememberMe()
2: {
3:
4: }
5:
6: public void LoginDoNotRememberMe()
7: {
8:
9: }
Instead of overloading Login and making the user have to decide which overload to call and pass in a parameter, we have elected to create two differently named methods which take 0 parameters and clearly state what they are going to do.
I’m not saying you should never write overloads, but anytime you see an overload in your code base, you should stop and think if it would be more clear to make that overloaded method into two different methods that can eliminate one or more of the parameters.
Any time you are restricting the number of choices someone using your code has to make, you are making that code simpler to use.
If you don’t believe me, consider why the iPhone has only one button.
As always, you can subscribe to this RSS feed to follow my posts on elegant code. Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week. Also, you can follow me on twitter here.
Tags: - Virtualization, Application Packaging, Architecture, Craftsmanship
Posted by RJ Owen on Jun 18, 2010 in
- Silver Light |
View Original Article
The Swiz micro-architecture for Flex development is nearing version 1.0. This is an important milestone for the Swiz team, some of whom have been working on the product for over two years new. If you haven't tried Swiz yet now is a great time to start. If you've been using Swiz for a while, make sure you submit any bugs for 1.0 before it's too late!
Tags: - Virtualization, Application Packaging, Architecture, Blogs, swiz
Posted by John Sonmez on Apr 25, 2010 in
- Dotnet,
- Silver Light |
View Original Article
It is not enough to just write code that is clean and self-documenting. Eliminating comments and replacing them with clear variable and method names, will tell the reader of your code clearly what it is doing, but it will not properly express why it is doing it.
If you recall from my original post on Elegant code, I stated that elegant code is:
Something that is simple yet effective, delivered with grace.
By writing self-documenting code we are hopefully able to achieve some of the aspects of simplicity and grace, but it tells us nothing about the effectiveness of the code.
Bringing the dead to life
Throwing out comments is a debatable topic. It raises quite a bit of controversy, as you can see from some of the comments on my post about the subject. The reason, perhaps, that so many people are so staunchly opposed to the idea, is because they are worried, and rightly so, that throwing out comments will reduce the documentation of what the code is doing.
Think about that for a second. Is documentation of what the code is doing important? It better be. What we are trying to accomplish by writing self-documenting code instead of comments, is to take the vessel, which is the code itself, and make that same vessel be the documentation of what the code does. It is by doing this that we creating a living representation of the functionality of the code. Comments are akin to a dead representation of the functionality of the code because they do not change automatically with the code.
I diverge to talk about comments so that I can draw a parallel to another form of documentation which is valuable and should be considered necessary. That other set of documentation is requirements. Have you ever written requirements documents? Have you ever captured requirements from the customer and put them into UML diagrams, or perhaps plopped them into some templated Word document, which is never updated again, and no one reads, because no one trusts it is correct? Wouldn’t it be great if we would replace that dead document or set of documents, with a living one?
The good news is we can, and some of us have. And I fully expect this recommendation will be just as controversial, because I am suggesting that we don’t have to write low level specifications of the system at all, instead we can write good unit tests. When we do this, we are taking a dead form of document and bringing it to life.
Unit tests tell us why and how our code is effective
If
i = 5; // Widget count defaults to five.
is replaced with
widgetCount = DEFAULT_WIDGET_COUNT;
then
1.1.5 When a new widget is created, the widget count should be increased by one.
is replaced with
public void When_NewWidgetIsCreated_Then_WidgetCountIsIncreasedByOne()
{
WidgetFactory.Count = 3;
WidgetFactory.CreateNew();
assertEquals(4, WidgetFactory.Count);
}
The unit test is replacing the low level requirement, which is somewhat open to interpretation and untied to the code, with an absolute and completely tied-to-the-code, specific requirement.
The unit test is telling us why our code is built the way it is. It is telling us what requirement that particular structure of code is trying to address. It is telling us what end result that code is trying to accomplish and what the expectations are on the results of a given condition.
The unit test is telling us how the code is to be used in order to achieve its result. It is serving as a living reference to the syntax and use of the code we built. Instead of providing instructions on how to use our API, we are providing a living example, and proof that it will indeed work. Examples are often much more effective than instructions anyway.
What exactly are we replacing?
At this point we are not trying to replace all the documentation of the system (at this point).
With self-documenting code, we sought to eliminate comments, and replace them with good variable and method names.
With unit tests, we seek to eliminate technical documentation and requirements of the system, that is targeted at a developer or technical audience.
We are NOT trying to eliminate high level specifications of the system, or use cases. Unit tests DO NOT replace that kind of documentation! We will talk about replacing that kind of documentation when we talk about automated functional or system tests.
Simply put, any kind of documentation that you would give to a developer so they understand how the system works and how to use the code or APIs, can be easily replaced by writing good unit tests.
Our simple goal is to replace the “dead” documentation (meaning that it does not update automatically with the thing it is documenting), with “living” documentation in the form of unit tests.
One last point. I want to be clear that I am not saying that having unit tests automatically results in the ability to replace technical documentation. Just like having long-named methods and variables doesn’t automatically replace the need for comments. It is a matter of the quality of the unit tests that are written, just as it is a matter of the quality of the self-documenting code.
As always, you can subscribe to this RSS feed to follow my posts on elegant code. Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week. Also, you can follow me on twitter here.
Tags: - Virtualization, Agile, Application Packaging, Architecture, Craftsmanship, Documentation, Unit Testing
Posted by cory.isakson on Mar 15, 2010 in
- Dotnet,
- Silver Light |
View Original Article
In this post I will begin introducing the architectural style known as Representational State Transfer (REST). REST is viable for both services and applications. Wrap your mind around this style and you will quickly see how straightforward it is and where it might fit in your solutions.
Resources
Resources are at the heart of REST. You are already used to resources as a web browsing consumer. A resource is not something specific to REST, instead it is the first thing you probably want to consider when architecting a RESTful application. A resource is simply the entity, item, or thing you want to expose.
Perhaps you have approached application architecture using one or many of several modeling and design techniques. Data First practitioners typically begin with databases and data models. DDD proponents like to begin by modeling around business entities and interactions, while their cousins in the BDD camp model around business activities.
When you decide to apply REST you will need to think a lot more about data entities and domain objects as resources. Your existing models may or may not closely map to resources. The shift in thinking may appear slight, but is very important. It centers around making things addressable. Each resources must by uniquely identifiable as we will see in the next section. We are used to identity with most data entities, but our domain objects may not always be as easily identifiable. Likewise, our data entites may have identity, but not map to a resource.
Consider the classic customer and order scenario for example. If each customer and each order can be identified then it will be easy to design RESTful systems around them. However, if the model requires a lot of context then our challenge is a little bit larger. Perhaps we must first identify a partner, then a year, then a customer, and finally the order. Yes, that is a design smell in general. It makes fetching an order very difficult. Developing RESTfuly would only further expose that difficulty. Identifying your resources up front will help you reduce the possible impedance mismatches you might end up with between what you want to expose and your data or domain models.
REST is about interacting with Resources!
URI’s
REST defines the identity of a resource via URI. Each resources has a unique address in URL form (ie. using the http protocol). Interaction with a resource will take place at its URI. As an example, my twitter status feed resource URI is http://twitter.com/optionstrict. That URI is unique to my feed and that is what you expect to find at that URI. In the Twitter databases or domain models my account may be referred to by the string optionstrict, or perhaps as some random number or guid.
To consume my status history via a service interface twitter provides another URI at http://api.twitter.com/1/statuses/user_timeline.json?screen_name=optionstrict. I would actually prefer to have access at the same URI for html, json, and xml formats. Twitter probably has its reasons for distinguishing API access from HTML rendering, but they have actually complicated their architecture by doing so. When designing the URI’s for your resources, make them easy for your users to work with.
Representation
Lets continue with the twitter example to describe what is meant by Representation. Given a URI and a Resource, what will your consumers receive when they issue a GET request to the URI? Twitter chose a representation of my account and included status history and profile for the response at http://twitter.com/optionstrict. They decided to put a representation of my profile photo at http://twitter.com/account/profile_image/optionstrict. In your REST solutions you will need to consider how you want to represent a resource at its URI. Each representation will have a unique URI.
Representations are also important for manipulating resources. You must define the representation required to create and update resources. Twitter status updates require a text representation with a maximum of 140 characters. They allow additional values in the status representation, such as latitude and longitude. Your REST solutions similarly must define representations for Requests and Responses.
I hope that this short introduction has helped you to see that the core essence of REST is simple and fairly obvious. As you look at your current solutions what are the resources you are exposing? Could you make those resources identifiable by URI? What representation would you place at each URI? What representation would you require for manipulating a given resource?
Also, notice I did not mention much about data formats, Content Type, Mime, etc. Those details can cloud your design if you try to start with them. If you can’t wait for my post about how REST handles html, json, xml from the same URI, then start googling Content Negotiation, Accept header, and Content-Type header.
Tags: - Virtualization, Application Packaging, Architecture, Resources, WebServices
Posted by Mark Nijhof on Dec 22, 2009 in
- Dotnet |
View Original Article
I received a couple questions about the Specification Framework that I use in the CQRS example and thought lets talk about that for a bit. The first thing that should be underlined is that this is _not_ a framework, they are a few classes and extension methods that rely on NUnit for the actual assertions and and Moq for mocking of the dependencies. I got the initial bits from Greg Young at his DDD course which I extended a little bit for my specific needs.
I have the following base test fixture classes:
- BaseTestFixture
- BaseTestFixture<TSubjectUnderTest>
- AggregateRootTestFixture<TAggregateRoot>
- CommandTestFixture<TCommand, TCommandHandler, TAggregateRoot>
- EventTestFixture<TEvent, TEventHandler>
- PresenterTestFixture<TPresenter>
These different classes are all very specific towards a specific need, which is a direct opposite from what a framework usually provides.
Black box
I try my best to make my tests treat the subject under test (SUT) as a black box, meaning that in my tests I don’t directly interact with the actual class that I am testing. Instead I want to trigger the behavior by executing behavior that lies further outside. The behavior that triggers the behavior on the SUT may be an actual implementation, or it could be a fake.
The same applies to the result of the behavior that gets tested, instead of verifying some state in the SUT I want to verify what happens outside of the SUT. So what matters is that I test the behavior not the state of the subject under test.
I also try to get further away from the SUT then its immediate usage. Doing so makes the tests less brittle for change. This in itself is not always an easy task, but I recommend you try it anyway.
The BaseTestFixture
This is the simplest test fixture class that I have and I use this for and I actually don’t use this anywhere in the example code, but it serves a really good basic overview of the semantics that are shared among the other test fixture classes.
1 namespace Test.Fohjin.DDD
2 {
3 [Specification]
4 public abstract class BaseTestFixture
5 {
6 protected Exception CaughtException;
7 protected virtual void Given() { }
8 protected abstract void When();
9 protected virtual void Finally() { }
10
11 [Given]
12 public void Setup()
13 {
14 CaughtException = new ThereWasNoExceptionButOneWasExpectedException();
15 Given();
16
17 try
18 {
19 When();
20 }
21 catch (Exception exception)
22 {
23 CaughtException = exception;
24 }
25 finally
26 {
27 Finally();
28 }
29 }
30 }
31
32 public class GivenAttribute : SetUpAttribute { }
33
34 public class ThenAttribute : TestAttribute { }
35
36 public class SpecificationAttribute : TestFixtureAttribute { }
37 }
It is following the Given When Then (GWT) approach, and as you can see it is really simple. Also note that I introduced some other named attributes by simply inheriting from the default NUnit attributes, this was purely done to stay with the GWT approach.
Below here is an incredible KISS example of how you would use this BaseTestFixture, which I believe doesn’t need further explanation. (I know I am misusing the term KISS here, but I thought if was fitting anyway).
1 namespace Test.Fohjin.DDD
2 {
3 public class Very_adding_a_number_to_the_subject_under_test : BaseTestFixture
4 {
5 private int SubjectUnderTest;
6
7 protected override void Given()
8 {
9 SubjectUnderTest = 2;
10 }
11
12 protected override void When()
13 {
14 SubjectUnderTest += 2;
15 }
16
17 [Then]
18 public void Then_the_new_value_of_the_subject_under_test_will_be_4()
19 {
20 SubjectUnderTest.WillBe(4);
21 }
22 }
23 }
The BaseTestFixture<TSubjectUnderTest>
Now we are getting into a more interesting case because now my subject under test is actually provided by the generic parameter of the base test fixture class. And to be honest this class is only used with 12 specifications out of the 122 specification classes. This is mostly because it is still a very generic solution, but again a nice way to ease into it.
1 namespace Test.Fohjin.DDD
2 {
3 [Specification]
4 public abstract class BaseTestFixture<TSubjectUnderTest>
5 {
6 private Dictionary<Type, object> mocks;
7
8 protected Dictionary<Type, object> DoNotMock;
9 protected TSubjectUnderTest SubjectUnderTest;
10 protected Exception CaughtException;
11 protected virtual void SetupDependencies() { }
12 protected virtual void Given() { }
13 protected abstract void When();
14 protected virtual void Finally() { }
15
16 [Given]
17 public void Setup()
18 {
19 mocks = new Dictionary<Type, object>();
20 DoNotMock = new Dictionary<Type, object>();
21 CaughtException = new ThereWasNoExceptionButOneWasExpectedException();
22
23 BuildMocks();
24 SetupDependencies();
25 SubjectUnderTest = BuildSubjectUnderTest();
26
27 Given();
28
29 try
30 {
31 When();
32 }
33 catch (Exception exception)
34 {
35 CaughtException = exception;
36 }
37 finally
38 {
39 Finally();
40 }
41 }
42
43 public Mock<TType> OnDependency<TType>() where TType : class
44 {
45 return (Mock<TType>)mocks[typeof(TType)];
46 }
47
48 private TSubjectUnderTest BuildSubjectUnderTest()
49 {
50 var constructorInfo = typeof(TSubjectUnderTest).GetConstructors().First();
51
52 var parameters = new List<object>();
53 foreach (var mock in mocks)
54 {
55 object theObject;
56 if (!DoNotMock.TryGetValue(mock.Key, out theObject))
57 theObject = ((Mock) mock.Value).Object;
58
59 parameters.Add(theObject);
60 }
61
62 return (TSubjectUnderTest)constructorInfo.Invoke(parameters.ToArray());
63 }
64
65 private void BuildMocks()
66 {
67 var constructorInfo = typeof(TSubjectUnderTest).GetConstructors().First();
68
69 foreach (var parameter in constructorInfo.GetParameters())
70 {
71 mocks.Add(parameter.ParameterType, CreateMock(parameter.ParameterType));
72 }
73 }
74
75 private static object CreateMock(Type type)
76 {
77 var constructorInfo = typeof(Mock<>).MakeGenericType(type).GetConstructors().First();
78 return constructorInfo.Invoke(new object[] { });
79 }
80 }
81 }
Wow there is _a lot_ more going on here! You are right, because here I make the base test fixture responsible for instantiating the subject under test, including providing mocks for any dependencies that it may have. So it is an auto mocker as well, but the interesting part here is that it puts a reference of the injected mocks in a collection that you can access inside your tests by using the OnDependency<TType> method that returns a Moq object.
Take a look at a specification using this base test fixture class:
1 namespace Test.Fohjin.DDD.Scenarios.Receiving_money_transfer
2 {
3 public class When_receiving_a_money_transfer : BaseTestFixture<MoneyReceiveService>
4 {
5 protected override void SetupDependencies()
6 {
7 OnDependency<IReportingRepository>()
8 .Setup(x => x.GetByExample<AccountReport>(It.IsAny<object>()))
9 .Returns(new List<AccountReport> { new AccountReport(Guid.NewGuid(), Guid.NewGuid(), "AccountName", "target account number") });
10 }
11
12 protected override void When()
13 {
14 SubjectUnderTest.Receive(new MoneyTransfer("source account number", "target account number", 123.45M));
15 }
16
17 [Then]
18 public void Then_the_newly_created_account_will_be_saved()
19 {
20 OnDependency<IBus>().Verify(x => x.Publish(It.IsAny<ReceiveMoneyTransferCommand>()));
21 }
22 }
23 }
So the first thing you see is the method SetupDependencies that is requesting the mock object for injected type IReporintgRepository and it is using the Moq way of setting up the Mock object. This is only needed when in your specification you need the mocks to be setup in a specific way. I intentionally separated the SetupDependencies from the Given as they may be two different things. And in the actual test you see the usage of the OnDependency method again where its being used to verify that something was indeed triggered on the injected class.
Now indeed this is not really treating the subject under test as a black box, for example in the When I make a direct call to a method on the subject under test. So my test knows about this now, meaning when it changes I need to change this test as well. So lets take a look where I go a bit further into the black box mentality.
The PresenterTestFixture<TPresenter>
Here I am not going to show you the code of the PresenterTestFixture implementation as it is almost identical the the previous base test fixture. So lets go straight to an actual specification:
1 namespace Test.Fohjin.DDD.Scenarios.Adding_a_new_client
2 {
3 public class When_in_the_GUI_the_phone_number_of_the_new_client_is_saved : PresenterTestFixture<ClientDetailsPresenter>
4 {
5 private object CreateClientCommand;
6
7 protected override void SetupDependencies()
8 {
9 OnDependency<IPopupPresenter>()
10 .Setup(x => x.CatchPossibleException(It.IsAny<Action>()))
11 .Callback<Action>(x => x());
12
13 OnDependency<IBus>()
14 .Setup(x => x.Publish(It.IsAny<object>()))
15 .Callback<object>(x => CreateClientCommand = x);
16 }
17
18 protected override void Given()
19 {
20 Presenter.SetClient(null);
21 Presenter.Display();
22 On<IClientDetailsView>().ValueFor(x => x.ClientName).IsSetTo("New Client Name");
23 On<IClientDetailsView>().FireEvent(x => x.OnFormElementGotChanged += null);
24 On<IClientDetailsView>().FireEvent(x => x.OnSaveNewClientName += null);
25
26 On<IClientDetailsView>().ValueFor(x => x.Street).IsSetTo("Street");
27 On<IClientDetailsView>().ValueFor(x => x.StreetNumber).IsSetTo("123");
28 On<IClientDetailsView>().ValueFor(x => x.PostalCode).IsSetTo("5000");
29 On<IClientDetailsView>().ValueFor(x => x.City).IsSetTo("Bergen");
30 On<IClientDetailsView>().FireEvent(x => x.OnFormElementGotChanged += null);
31 On<IClientDetailsView>().FireEvent(x => x.OnSaveNewAddress += null);
32
33 On<IClientDetailsView>().ValueFor(x => x.PhoneNumber).IsSetTo("1234567890");
34 On<IClientDetailsView>().FireEvent(x => x.OnFormElementGotChanged += null);
35 }
36
37 protected override void When()
38 {
39 On<IClientDetailsView>().FireEvent(x => x.OnSaveNewPhoneNumber += null);
40 }
41
42 [Then]
43 public void Then_the_save_button_will_be_disabled()
44 {
45 On<IClientDetailsView>().VerifyThat.Method(x => x.DisableSaveButton()).WasCalled();
46 }
47
48 [Then]
49 public void Then_a_create_client_command_with_all_collected_information_will_be_published()
50 {
51 On<IBus>().VerifyThat.Method(x => x.Publish(It.IsAny<CreateClientCommand>())).WasCalled();
52
53 CreateClientCommand.As<CreateClientCommand>().ClientName.WillBe("New Client Name");
54 CreateClientCommand.As<CreateClientCommand>().Street.WillBe("Street");
55 CreateClientCommand.As<CreateClientCommand>().StreetNumber.WillBe("123");
56 CreateClientCommand.As<CreateClientCommand>().PostalCode.WillBe("5000");
57 CreateClientCommand.As<CreateClientCommand>().City.WillBe("Bergen");
58 CreateClientCommand.As<CreateClientCommand>().PhoneNumber.WillBe("1234567890");
59 }
60
61 [Then]
62 public void Then_overview_panel_will_be_shown()
63 {
64 On<IClientDetailsView>().VerifyThat.Method(x => x.Close()).WasCalled();
65 }
66 }
67 }
Again there is the setting up of a dependency in the beginning and then there is the Given method, Presenter in this case is the subject under test, so you can see that the specification still knows about the SUT in the Given, but you will notice that this is not used in either the When or the Then.
Hey what is that On thing in there? Well that is a very small DSL wrapping the Moq API. I did this to make it slightly more readable, and in this case it is very adapt towards working with a view and presenter. In the Given I am setting up my IClientDetailsView with the correct data, but I am also simulating that an event was triggered. This is not logic that the test is concerned about, all we do here is bring the view and the presenter in the correct state for this particular specification. So instead of setting these things directly on the presenter this will all be directed from the view.
Then in the When we again fire an event from the view, but in this case it is the going to trigger the behavior on the presenter that we want to verify. And in the Then methods we verify on the view again that the presenter actually did the correct things, but we also verify on other dependencies that the correct methods where called, in this case the IBus.
I am not completely happy with the mini DSL yet, but I think it is cleaner then the default Moq API. Just for those that are curious, here is the mini DSL which gets returned by the On method:
1 namespace Test.Fohjin.DDD
2 {
3 public class MockDsl<TType> where TType : class
4 {
5 private readonly IDictionary<Type, object> _mocks;
6
7 public MockDsl(IDictionary<Type, object> mocks)
8 {
9 _mocks = mocks;
10 }
11
12 public ValueSetter<TType, TProperty> ValueFor<TProperty>(Expression<Func<TType, TProperty>> selector)
13 {
14 return new ValueSetter<TType, TProperty>(_mocks, selector);
15 }
16
17 public void FireEvent(Action<TType> fieldSelector)
18 {
19 if (!_mocks.ContainsKey(typeof(TType)))
20 throw new Exception(string.Format("The requested dependency '{0}' is not specified in the constructor", typeof(TType).FullName));
21
22 var mock = (Mock<TType>)_mocks[typeof(TType)];
23 mock.Raise(fieldSelector);
24 }
25
26 public Verifier<TType> VerifyThat { get { return new Verifier<TType>(_mocks); } }
27 }
28
29 public class Verifier<TType> where TType : class
30 {
31 private readonly IDictionary<Type, object> _mocks;
32
33 public Verifier(IDictionary<Type, object> mocks)
34 {
35 _mocks = mocks;
36 }
37
38 public void ValueIsSetFor(Action<TType> selector)
39 {
40 if (!_mocks.ContainsKey(typeof(TType)))
41 throw new Exception(string.Format("The requested dependency '{0}' is not specified in the constructor", typeof(TType).FullName));
42
43 var mock = (Mock<TType>)_mocks[typeof(TType)];
44 mock.VerifySet(selector);
45 }
46
47 public MethodVerifier<TType> Method(Expression<Action<TType>> selector)
48 {
49 return new MethodVerifier<TType>(_mocks, selector);
50 }
51 }
52
53 public class MethodVerifier<TType> where TType : class
54 {
55 private readonly IDictionary<Type, object> _mocks;
56 private readonly Expression<Action<TType>> _fieldSelector;
57
58 public MethodVerifier(IDictionary<Type, object> mocks, Expression<Action<TType>> fieldSelector)
59 {
60 _mocks = mocks;
61 _fieldSelector = fieldSelector;
62 }
63
64 public void WasCalled()
65 {
66 if (!_mocks.ContainsKey(typeof(TType)))
67 throw new Exception(string.Format("The requested dependency '{0}' is not specified in the constructor", typeof(TType).FullName));
68
69 var mock = (Mock<TType>)_mocks[typeof(TType)];
70 mock.Verify(_fieldSelector);
71 }
72 }
73
74 public class ValueSetter<TType, TProperty> where TType : class
75 {
76 private readonly IDictionary<Type, object> _mocks;
77 private readonly Expression<Func<TType, TProperty>> _fieldSelector;
78
79 public ValueSetter(IDictionary<Type, object> mocks, Expression<Func<TType, TProperty>> fieldSelector)
80 {
81 _mocks = mocks;
82 _fieldSelector = fieldSelector;
83 }
84
85 public void IsSetTo(TProperty value)
86 {
87 if (!_mocks.ContainsKey(typeof(TType)))
88 throw new Exception(string.Format("The requested dependency '{0}' is not specified in the constructor", typeof(TType).FullName));
89
90 var mock = (Mock<TType>)_mocks[typeof(TType)];
91 mock.SetupGet(_fieldSelector).Returns(value);
92 }
93 }
94 }
CQRS and Event Sourcing
By combining CQRS and Event Sourcing we get an architecture that is very suitable for black box testing its behavior, which was a real eye opener when Greg demonstrated this to me. He says that the way to bring your aggregate root back into the desired state is to playback the events that are needed to do so. Then you can execute the behavior on the aggregate root, and finally to actually verify your behavior you retrieve the published events and verify that they are as expected.
Now the beauty of this is that the setup and the verification this will work on any aggregate root because we are using the IEventProvider interface there that they all implement. The only actual knowledge about the aggregate root that remains is the specific behavior that you trigger.
But I went a little bit further then what was shown during the course, I am saying that instead of executing the behavior on the aggregate root we could also just provide the command that should trigger this behavior to be executed. Because the command would be handled by a specific command handler which in turn would execute the domain behavior.
Now below here is the command test fixture that allows me to do just that, I need to provide the actual command, command handler and aggregate root types that are to be used in this specification.
1 namespace Test.Fohjin.DDD
2 {
3 [Specification]
4 public abstract class CommandTestFixture<TCommand, TCommandHandler, TAggregateRoot>
5 where TCommand : class, ICommand
6 where TCommandHandler : class, ICommandHandler<TCommand>
7 where TAggregateRoot : class, IOrginator, IEventProvider<IDomainEvent>, new()
8 {
9 private IDictionary<Type, object> mocks;
10
11 protected TAggregateRoot AggregateRoot;
12 protected ICommandHandler<TCommand> CommandHandler;
13 protected Exception CaughtException;
14 protected IEnumerable<IDomainEvent> PublishedEvents;
15 protected virtual void SetupDependencies() { }
16 protected virtual IEnumerable<IDomainEvent> Given()
17 {
18 return new List<IDomainEvent>();
19 }
20 protected virtual void Finally() { }
21 protected abstract TCommand When();
22
23 [Given]
24 public void Setup()
25 {
26 mocks = new Dictionary<Type, object>();
27 CaughtException = new ThereWasNoExceptionButOneWasExpectedException();
28 AggregateRoot = new TAggregateRoot();
29 AggregateRoot.LoadFromHistory(Given());
30
31 CommandHandler = BuildCommandHandler();
32
33 SetupDependencies();
34 try
35 {
36 CommandHandler.Execute(When());
37 PublishedEvents = AggregateRoot.GetChanges();
38 }
39 catch (Exception exception)
40 {
41 CaughtException = exception;
42 }
43 finally
44 {
45 Finally();
46 }
47 }
48
49 public Mock<TType> OnDependency<TType>() where TType : class
50 {
51 return (Mock<TType>)mocks[typeof(TType)];
52 }
53
54 private ICommandHandler<TCommand> BuildCommandHandler()
55 {
56 var constructorInfo = typeof(TCommandHandler).GetConstructors().First();
57
58 foreach (var parameter in constructorInfo.GetParameters())
59 {
60 if (parameter.ParameterType == typeof(IDomainRepository<IDomainEvent>))
61 {
62 var repositoryMock = new Mock<IDomainRepository<IDomainEvent>>();
63 repositoryMock.Setup(x => x.GetById<TAggregateRoot>(It.IsAny<Guid>())).Returns(AggregateRoot);
64 repositoryMock.Setup(x => x.Add(It.IsAny<TAggregateRoot>())).Callback<TAggregateRoot>(x => AggregateRoot = x);
65 mocks.Add(parameter.ParameterType, repositoryMock);
66 continue;
67 }
68
69 mocks.Add(parameter.ParameterType, CreateMock(parameter.ParameterType));
70 }
71
72 return (ICommandHandler<TCommand>)constructorInfo.Invoke(mocks.Values.Select(x => ((Mock) x).Object).ToArray());
73 }
74
75 private static object CreateMock(Type type)
76 {
77 var constructorInfo = typeof (Mock<>).MakeGenericType(type).GetConstructors().First();
78 return constructorInfo.Invoke(new object[]{});
79 }
80 }
81
82 public class ThereWasNoExceptionButOneWasExpectedException : Exception {}
83 }
Please note that the Given method now returns an IEnumerable<IDomainEvent> this is to be used to provide the events that are needed to bring the aggregate root into the correct state for this specification. This is using the exact same mechanism as the actual code uses to make state changes in the aggregate root, so there cannot be a case that you are testing your aggregate root using a state that it cannot get into.
The When method returns the expected command, so all you do there is create the command with the correct information and return it to the specification.
Then in the try catch block you may have noticed that a command handler is executing the provided command and that after that the events are being retrieved from the aggregate root. These events are what you would verify to make sure your domain behavior is correct.
But this may all sound very abstract, lets look at a simple specification and see how clean and readable is really is:
1 namespace Test.Fohjin.DDD.Scenarios.Withdrawing_cash
2 {
3 public class When_withdrawing_cash : CommandTestFixture<WithdrawlCashCommand, WithdrawlCashCommandHandler, ActiveAccount>
4 {
5 protected override IEnumerable<IDomainEvent> Given()
6 {
7 yield return new AccountOpenedEvent(Guid.NewGuid(), Guid.NewGuid(), "AccountName", "1234567890");
8 yield return new CashDepositedEvent(20, 20);
9 }
10
11 protected override WithdrawlCashCommand When()
12 {
13 return new WithdrawlCashCommand(Guid.NewGuid(), 5);
14 }
15
16 [Then]
17 public void Then_a_cash_withdrawn_event_will_be_published()
18 {
19 PublishedEvents.Last().WillBeOfType<CashWithdrawnEvent>();
20 }
21
22 [Then]
23 public void Then_the_published_event_will_contain_the_amount_and_new_account_balance()
24 {
25 PublishedEvents.Last<CashWithdrawnEvent>().Balance.WillBe(15);
26 PublishedEvents.Last<CashWithdrawnEvent>().Amount.WillBe(5);
27 }
28 }
29 }
So you provide historical events to bring the aggregate root into the expected state, you fire of the command, then you verify the published events to ensure your domain behavior is correct. If you choose the correct naming for your events and commands, then a business person would be able to understand the specification. Especially if you parse the text and do a little bit of formatting.
Where is Should?
Hey what are all those WillBe and WillBeOfType things that I see in your specifications, should they not be ShouldBe and ShouldBeOfType? Well I used to think so as well, until I attended a presentation by Kevlin Henney at NDC where he explained that Should is not specific enough. Should indicates that it might not. I like to use the example; “I should really do the dishes, but I won’t”. By using Will Be and Must you are much more dictating what will or must happen, its not a question anymore.
Finally
I am completely taken by this approach and as you see you don’t need a big BDD framework for this. I think using something like this gives a good learning experience before going towards an actual BDD framework like MSpec. Also Uncle Bob just wrote a good post about to not abuse the Given When Then approach and also take a look at the Mocks aren’t Stubs article by Martin Fowler.
By now you must <grin> understand that I like to throw with code examples so yes the post is very long, but I hope it provides enough value instead of just confusion.
Tags: - Virtualization, Application Packaging, Architecture, Conventions, CQRS, DDD, TDD
Posted by Mark Nijhof on Dec 19, 2009 in
- Dotnet |
View Original Article
I was reading Ayende’s blog post about building UI based on conventions and thought; hey I have something similar in my CQRS example. And since this is the least interesting part of the whole example I guess it will be missed by many, and I can’t let that happen.
Passive View
The example has a Win Forms application in there that is build accordingly to the Passive View pattern, so my actual forms are being dumbed down to simple views without any logic in them, well almost no logic. Then I have presenters that have the actual logic in them, or delegate the logic to other responsible entities (services or whatever).
The reason for doing this is because you want to be able to test the behavioral parts of your code as simple as possible, and nothing is more simple then being able to unit test your behavior, hey even better drive your design / behavior through Test-Driven Development Design (TDD). Imagine how hard that would be to do when not abstracting these different responsibilities from each other (hehe I am sure some of you don’t even need to imagine this
).
I realize the Win Forms is so not _in_ anymore and that nobody uses them, but perhaps what I show you here makes you think about other areas that this could be applied to.
The View
The view is responsible for displaying information to a user, capturing user requests, and … uhm no that’s it. Let’s take a look at a simple view.
1 namespace Fohjin.DDD.BankApplication.Views
2 {
3 public partial class ClientSearchForm : Form, IClientSearchFormView
4 {
5 public ClientSearchForm()
6 {
7 InitializeComponent();
8 RegisterClientEvents();
9 }
10
11 public event EventAction OnCreateNewClient;
12 public event EventAction OnOpenSelectedClient;
13
14 private void RegisterClientEvents()
15 {
16 addANewClientToolStripMenuItem.Click += (s, e) => OnCreateNewClient();
17 _clients.Click += (s, e) => OnOpenSelectedClient();
18 }
19
20 public IEnumerable<ClientReport> Clients
21 {
22 get { return (IEnumerable<ClientReport>)_clients.DataSource; }
23 set { _clients.DataSource = value; }
24 }
25
26 public ClientReport GetSelectedClient()
27 {
28 return (ClientReport)_clients.SelectedItem;
29 }
30 }
31 }
So what is happening here? As you can see there are two public events declared and there are two properties that provide access to some form controls. The interesting thing here is that the two public events are wired to two events from two form controls. But hey nothing is happening; no behavior, no calls to services or anything. Below here is the declaration of the interface that the form implements.
1 namespace Fohjin.DDD.BankApplication.Views
2 {
3 public interface IClientSearchFormView : IView
4 {
5 IEnumerable<ClientReport> Clients { get; set; }
6 ClientReport GetSelectedClient();
7 event EventAction OnCreateNewClient;
8 event EventAction OnOpenSelectedClient;
9 }
10 }
Here are both the two public events and the two properties that provide access to two form controls, of course the implementation could be anything. This interface is used by the presenter to control the view.
The Presenter
So the presenter is responsible for controlling the view; which includes setting and retrieving data and executing behavior that is triggered by the user of the view. Below is the presenter that is responsible for managing the previous mentioned view.
1 namespace Fohjin.DDD.BankApplication.Presenters
2 {
3 public class ClientSearchFormPresenter : Presenter<IClientSearchFormView>, IClientSearchFormPresenter
4 {
5 private readonly IClientSearchFormView _clientSearchFormView;
6
7 public ClientSearchFormPresenter(IClientSearchFormView clientSearchFormView) : base(clientSearchFormView)
8 {
9 _clientSearchFormView = clientSearchFormView;
10 }
11
12 public void CreateNewClient()
13 {
14 // Do something
15 }
16
17 public void OpenSelectedClient()
18 {
19 // Do something
20 }
21
22 public void Display()
23 {
24 LoadData();
25 try
26 {
27 _clientSearchFormView.ShowDialog();
28 }
29 finally
30 {
31 _clientSearchFormView.Dispose();
32 }
33 }
34
35 private void LoadData()
36 {
37 // Do something
38 }
39 }
40 }
For simplicity I removed any other external dependencies and replaced the behavior with a comment “Do something”. Talking about external dependencies; the interface that is implemented by the view is injected into the presenter, this is interesting.
Look at the Display method, there you see that the view that is injected first gets its data loaded and then actually gets activated. This means that the view will not get its own data, but that the presenter will provide it to the view, for this the presenter will use the two properties that where declared in the interface. And it means that the presenter is responsible for activating the view. This is different from how Win Forms works out of the box.
For this to work I had to change the Program class, here take a look:
1 namespace Fohjin.DDD.BankApplication
2 {
3 static class Program
4 {
5 /// <summary>
6 /// The main entry point for the application.
7 /// </summary>
8 [STAThread]
9 static void Main()
10 {
11 ApplicationBootStrapper.BootStrap();
12
13 var clientSearchFormPresenter = ObjectFactory.GetInstance<IClientSearchFormPresenter>();
14
15 Application.EnableVisualStyles();
16
17 clientSearchFormPresenter.Display();
18 }
19 }
20 }
Look at line 17 in there, the method Display is called on the presenter, which then prepares and activates the view.
But I can hear you think; what about these two events that where declared on that interface as well, you know “OnCreateNewClient” and “OnOpenSelectedClient”? I can see some obvious candidates “CreateNewClient” and “OpenSelectedClient” but they are not wired-up together. What gives?
The Magic
You must have noticed that the names are very similar and that they follow a certain pattern, this is the convention that I have chosen to use. Basically I call my event handlers the same as the events without the “On” prefix. Then I have a base presenter class without the word “Base” because that would be EVIL. And this class will wire-up the events with the event handlers for me.
1 namespace Fohjin.DDD.BankApplication.Presenters
2 {
3 public abstract class Presenter<TView> where TView : class, IView
4 {
5 protected Presenter(TView view)
6 {
7 HookUpViewEvents(view);
8 }
9
10 private void HookUpViewEvents(TView view)
11 {
12 var viewDefinedEvents = GetViewDefinedEvents();
13 var viewEvents = GetViewEvents(view, viewDefinedEvents);
14 var presenterEventHandlers = GetPresenterEventHandlers(viewDefinedEvents, this);
15
16 foreach (var viewDefinedEvent in viewDefinedEvents)
17 {
18 var eventInfo = viewEvents[viewDefinedEvent];
19 var methodInfo = GetTheEventHandler(viewDefinedEvent, presenterEventHandlers, eventInfo);
20
21 WireUpTheEventAndEventHandler(view, eventInfo, methodInfo);
22 }
23 }
24
25 private MethodInfo GetTheEventHandler(string viewDefinedEvent, IDictionary<string, MethodInfo> presenterEventHandlers, EventInfo eventInfo)
26 {
27 var substring = viewDefinedEvent.Substring(2);
28 if (!presenterEventHandlers.ContainsKey(substring))
29 throw new Exception(string.Format("\n\nThere is no event handler for event '{0}' on presenter '{1}' expected '{2}'\n\n", eventInfo.Name, GetType().FullName, substring));
30
31 return presenterEventHandlers[substring];
32 }
33
34 private void WireUpTheEventAndEventHandler(TView view, EventInfo eventInfo, MethodInfo methodInfo)
35 {
36 var newDelegate = Delegate.CreateDelegate(typeof(EventAction), this, methodInfo);
37 eventInfo.AddEventHandler(view, newDelegate);
38 }
39
40 private static IDictionary<string, MethodInfo> GetPresenterEventHandlers<TPresenter>(ICollection<string> actionProperties, TPresenter presenter)
41 {
42 return presenter
43 .GetType()
44 .GetMethods(BindingFlags.Instance | BindingFlags.Public)
45 .Where(x => Contains(actionProperties, x))
46 .ToList()
47 .Select(x => new KeyValuePair<string, MethodInfo>(x.Name, x))
48 .ToDictionary(x => x.Key, x => x.Value);
49 }
50
51 private static List<string> GetViewDefinedEvents()
52 {
53 return typeof(TView).GetEvents().Select(x => x.Name).ToList();
54 }
55
56 private static IDictionary<string, EventInfo> GetViewEvents(TView view, ICollection<string> actionProperties)
57 {
58 return view
59 .GetType()
60 .GetEvents()
61 .Where(x => Contains(actionProperties, x))
62 .ToList()
63 .Select(x => new KeyValuePair<string, EventInfo>(x.Name, x))
64 .ToDictionary(x => x.Key, x => x.Value);
65 }
66
67 private static bool Contains(ICollection<string> actionProperties, EventInfo x)
68 {
69 return actionProperties.Contains(x.Name);
70 }
71
72 private static bool Contains(ICollection<string> actionProperties, MethodInfo x)
73 {
74 return actionProperties.Contains(string.Format("On{0}", x.Name));
75 }
76 }
77 }
The abstract base class Presenter needs the view interface as the generic parameter of the view that the presenter controls. A reference to the actual view will be injected into the presenter class. Then the first thing that happens is that I get all the events declared from the provided interface. Then I get the actual events from the provided view, but only those that have been defined on the provided interface. This makes it possible to define multiple interfaces on the same view that get controlled by different presenters. After this I get all the public methods from the presenter.
Once I have the events form the view and the methods from the presenter then I can start matching them together. As I mentioned before in my case I use a very simple convention where the event is prefixed with “On” so in order to get the event handler I only need to search my event handler collection for a name of the event minus “On”. Then finally the event gets the event handler added to its collection of event handlers.
When there is no event handler for a provided event then I throw an exception, because I consider this to be a bug. There might be event handlers that does not have an event associated with it, but I consider that less harmful since this logic would not be called anyway. This exception will be visible in the unit tests for the presenter.
Reflection
Yes this relies very heavily on reflection, but for this scenario I don’t mind. Indeed it is slower, but the question is; will you notice this when displaying a form, and I don’t think you will. You could improve this code by for example making the WireUpEventAndEventHandler an action and cache those for the combination of the presenter and view interface, but I don’t think that is worth the effort.
The Specifications
I am going to leave you with the specifications that I have for the presenter that I used for this post. The whole presenter is being tested by setting data on the view and triggering events. I am not calling the methods directly on the presenter itself. And if you want to see more, then get the code from GitHub.
1 namespace Test.Fohjin.DDD.Scenarios.Opening_the_bank_application
2 {
3 public class When_in_the_GUI_openeing_the_bank_application : PresenterTestFixture<ClientSearchFormPresenter>
4 {
5 private List<ClientReport> _clientReports;
6
7 protected override void SetupDependencies()
8 {
9 _clientReports = new List<ClientReport> { new ClientReport(Guid.NewGuid(), "Client Name") };
10 OnDependency<IReportingRepository>()
11 .Setup(x => x.GetByExample<ClientReport>(null))
12 .Returns(_clientReports);
13 }
14
15 protected override void When()
16 {
17 Presenter.Display();
18 }
19
20 [Then]
21 public void Then_show_dialog_will_be_called_on_the_view()
22 {
23 On<IClientSearchFormView>().VerifyThat.Method(x => x.ShowDialog()).WasCalled();
24 }
25
26 [Then]
27 public void Then_client_report_data_from_the_reporting_repository_is_being_loaded_into_the_view()
28 {
29 On<IClientSearchFormView>().VerifyThat.ValueIsSetFor(x => x.Clients = _clientReports);
30 }
31 }
32 }
1 namespace Test.Fohjin.DDD.Scenarios.Adding_a_new_client
2 {
3 public class When_in_the_GUI_adding_a_new_client : PresenterTestFixture<ClientSearchFormPresenter>
4 {
5 protected override void When()
6 {
7 On<IClientSearchFormView>().FireEvent(x => x.OnCreateNewClient += delegate { });
8 }
9
10 [Then]
11 public void Then_client_report_data_from_the_reporting_repository_is_being_loaded_into_the_view()
12 {
13 On<IClientDetailsPresenter>().VerifyThat.Method(x => x.SetClient(null)).WasCalled();
14 }
15
16 [Then]
17 public void Then_display_will_be_called_on_the_view()
18 {
19 On<IClientDetailsPresenter>().VerifyThat.Method(x => x.Display()).WasCalled();
20 }
21 }
22 }
1 namespace Test.Fohjin.DDD.Scenarios.Displaying_client_details
2 {
3 public class When_in_the_GUI_opening_an_existing_client : PresenterTestFixture<ClientSearchFormPresenter>
4 {
5 private ClientReport _clientReport;
6
7 protected override void SetupDependencies()
8 {
9 OnDependency<IPopupPresenter>()
10 .Setup(x => x.CatchPossibleException(It.IsAny<Action>()))
11 .Callback<Action>(x => x());
12
13 _clientReport = new ClientReport(Guid.NewGuid(), "Client Name");
14
15 OnDependency<IClientSearchFormView>()
16 .Setup(x => x.GetSelectedClient())
17 .Returns(_clientReport);
18 }
19
20 protected override void When()
21 {
22 On<IClientSearchFormView>().FireEvent(x => x.OnOpenSelectedClient += delegate { });
23 }
24
25 [Then]
26 public void Then_get_selected_client_will_be_called_on_the_view()
27 {
28 On<IClientSearchFormView>().VerifyThat.Method(x => x.GetSelectedClient()).WasCalled();
29 }
30
31 [Then]
32 public void Then_client_report_data_from_the_reporting_repository_is_being_loaded_into_the_view()
33 {
34 On<IClientDetailsPresenter>().VerifyThat.Method(x => x.SetClient(_clientReport)).WasCalled();
35 }
36
37 [Then]
38 public void Then_display_will_be_called_on_the_view()
39 {
40 On<IClientDetailsPresenter>().VerifyThat.Method(x => x.Display()).WasCalled();
41 }
42 }
43 }
Tags: - Virtualization, Application Packaging, Architecture, Conventions
Posted by Mark Nijhof on Dec 8, 2009 in
- Dotnet |
View Original Article
This morning Aaron Jensen asked a really interesting question on Twitter “Should Aggregate Roots en Entities always keep their state if it is not needed for business decisions? Is firing events and relying on the reporting store enough?”. He really made me think, Aaron thanks for that!
So for example you have some behavior on your domain that gets called when a customer moves, this behavior will publish a Customer Moved event containing the new address. If the domain does not use the address information for any decision making, does it then need to be persisted in the aggregate root?
I guess it would greatly depend on whether or not you are using Event Sourcing to persist your published events (this is what I would suggest). If you do then I don’t see a problem in skipping storing the address information in the aggregate root. Because if at a later time you need the address information to make some decisions then it is easy to retrieve this from the events when reloading the aggregate root from the event store. You just create the address property and an internal event handler to process the Customer Moved event. Just make sure you delete the snapshots first.
But if you do not store all the events that you publish, but instead store only a snapshot then I would not skip storing the new address information, because in the end the domain is responsible for the state, not the reporting side. In other words, you can rebuild the reporting side from the domain, but you cannot necessarily do the same in reverse. So if you don’t store the address information and you need to rebuild the reporting store then you cannot do this.
So my conclusion is that the information should be available on the domain side. And when using CQRS and Event Sourcing to store the events instead of the internal state of the domain then that makes it possible to skip having the information in the domain structure, else not.
Tags: - Virtualization, Application Packaging, Architecture, CQRS, DDD
Posted by Mark Nijhof on Nov 20, 2009 in
- Dotnet |
View Original Article
As you may have seen in my previous post “CQRS à la Greg Young” now our domain aggregate root is responsible for publishing domain events indicating that some internal state has changed. In fact state changes within our aggregate root are _only_ allowed through such domain events. Secondly the internal event handlers are _not_ allowed to have any sort of business logic in them, they are _only_ supposed to set or update the internal state of the aggregate root directly from the data the event carries. Using these rules you completely separate the business logic from the state changes. This separation enables us to replay historical domain events without any business logic being triggered bringing it back to the same state as the original aggregate root.
Why is this important? Well now we can use these same domain events for our persistence using an Event Store, this pattern by Martin Fowler is called “Event Sourcing”. Obviously you don’t want to process a credit card or send an e-mail every time you load an aggregate root from the event store. Also from the time the original domain event was recorded and when the aggregate root is loaded from the event store the business logic that decided a state change was needed could have changed, this should not affect the actual historical state change. So this separation is to be taken seriously.
Domain events can also be used to signal something to the outside world (taken from the aggregate roots view point) that something has happened without having an actual state change. When persisting our domain events we would not differentiate between those two different domain events.
All domain events should be named with the ubiquitous language in mind, meaning that they should closely represent what the user intended to do in the same language as the user would use to explain it to you. By keeping all these domain events we gain a huge amount of knowledge about what happened and why it happened.
This means that our aggregate root gets the added responsibility of tracking these domain events, but I don’t see this as being any different then for example the proxy that NHibernate generates for you, except perhaps that it is not a proxy and that you have more control over what happens. But it is true your aggregate root has these added responsibilities.
So let us take a look at how the aggregate root provides this functionality, for obvious reasons we use a base class for this, but really all that is needed is that the aggregate root implements the following two interfaces:
1 namespace Fohjin.DDD.EventStore.Storage.Memento
2 {
3 public interface IOrginator
4 {
5 IMemento CreateMemento();
6 void SetMemento(IMemento memento);
7 }
8 }
The IOrginator interface is for the snapshot functionality which is an optimization technique for speeding up loading aggregate roots from the Event Store. As you can see it is using the “Memento” patter from the Gang Of Four book. I wanted to get this interface out of the way first; it is not needed, but does provide a good optimization for loading aggregate roots.
1 namespace Fohjin.DDD.EventStore
2 {
3 public interface IEventProvider
4 {
5 void Clear();
6 void LoadFromHistory(IEnumerable<IDomainEvent> domainEvents);
7 void UpdateVersion(int version);
8 Guid Id { get; }
9 int Version { get; }
10 IEnumerable<IDomainEvent> GetChanges();
11 }
12 }
The IEventProvider interface is the most interesting interface of the two, this one defines how domain events can be retrieved from the aggregate root and how historical domain events can be loaded back. It also defines that each aggregate root must have an Id and a Version, both of these are used by the event store, the Id is obvious so I won’t go into that, the version on the other hand may not be that obvious. The version is used to detect concurrency violations, meaning this is used to prevent conflicts that occur because between the time the command was send and the aggregate root was saved an other user or process has updated the same aggregate root. In this case we would throw an Concurrency Violation Exception which currently results in a rollback. In a future post I plan to look into how you could try to deal with these concurrency violations automatically.
Using domain events for state change
Now we will take a look at how these interfaces are implemented and how the implementation is used. The way I am going to go through the code is as if you where using R# going from method to method. So in order to get a more overall impression I would encourage you to look at the source code. The source code can be found here: http://github.com/MarkNijhof/Fohjin
Each aggregate root has to register the domain events and the internal event handlers with the base class. I am working on getting this as static information for the type since this will not change between different instances of the same type. As you can see I am registering the domain event type and an action to handle the specific type. As you can see the actions have the specific domain event as an input parameter.
1 private void registerEvents()
2 {
3 RegisterEvent<ClientCreatedEvent>(onNewClientCreated);
4 RegisterEvent<ClientMovedEvent>(onNewClientMoved);
5 }
6
7 private void onNewClientCreated(ClientCreatedEvent clientCreatedEvent)
8 {
9 Id = clientCreatedEvent.ClientId;
10 _clientName = new ClientName(clientCreatedEvent.ClientName);
11 _address = new Address(clientCreatedEvent.Street, clientCreatedEvent.StreetNumber, clientCreatedEvent.PostalCode, clientCreatedEvent.City);
12 _phoneNumber = new PhoneNumber(clientCreatedEvent.PhoneNumber);
13 }
14
15 private void onNewClientMoved(ClientMovedEvent clientMovedEvent)
16 {
17 _address = new Address(clientMovedEvent.Street, clientMovedEvent.StreetNumber, clientMovedEvent.PostalCode, clientMovedEvent.City);
18 }
The RegisterEvent method is defined in the BaseAggregateRoot class, here is a little bit of interesting logic going on where basically a new action is defined that has an IDomainEvent as an input parameter, that is how they can all be stored in the same Dictionary. Then inside this action the provided action is invoked where the input value is cast from an IDomainEvent to the actual expected type TEvent.
1 private readonly Dictionary<Type, Action<IDomainEvent>> _registeredEvents;
2 protected void RegisterEvent<TEvent>(Action<TEvent> eventHandler) where TEvent : class, IDomainEvent
3 {
4 _registeredEvents.Add(typeof(TEvent), theEvent => eventHandler(theEvent as TEvent));
5 }
So if we would write the example out of what is actually happening for the Client Created Event then it would look like this example below, and this is what is being stored in the _registeredEvents.
1 public void Delegate(IDomainEvent domainEvent)
2 {
3 onNewClientCreated(domainEvent as ClientCreatedEvent);
4 }
And below here is the private apply method that is being called from two different methods in the aggregate root base class. The method retrieves the action that is registered for the provided domain event, and than it invokes the action with the domain event as the input parameter. The apply method takes an IDomainEvent instead of the specific domain event and because of that we have the above mentioned logic.
1 private void apply(Type eventType, IDomainEvent domainEvent)
2 {
3 Action<IDomainEvent> handler;
4
5 if (!_registeredEvents.TryGetValue(eventType, out handler))
6 throw new UnregisteredDomainEventException(string.Format("The requested domain event '{0}' is not registered in '{1}'", eventType.FullName, GetType().FullName));
7
8 handler(domainEvent);
9 }
Let us take a look from where this apply method is being called, first we will look at some actual domain behavior in the aggregate root.
1 public void Withdrawl(Amount amount)
2 {
3 Guard();
4
5 IsBalanceHighEnough(amount);
6
7 var newBalance = _balance.Withdrawl(amount);
8
9 Apply(new CashWithdrawnEvent(newBalance, amount));
10 }
First we execute all our valuable domain logic, the business behavior. Then when we are satisfied that everything is ok and we know what type of state change we need to execute and we Apply a new domain event with the new internal state. The Apply method used here is a protected method on the BaseAgregateRoot. Btw there is nothing stating that there can only be one outcome, i.e. only one type of domain event being Applied.
1 protected void Apply<TEvent>(TEvent domainEvent) where TEvent : class, IDomainEvent
2 {
3 domainEvent.AggregateId = Id;
4 domainEvent.Version = GetNewEventVersion();
5 apply(domainEvent.GetType(), domainEvent);
6 _appliedEvents.Add(domainEvent);
7 }
When we Apply a domain event we will first assign the aggregate root Id to the event so that we can keep track to which aggregate root this event belongs to. Secondly we get a new version and assign this to the event, this is to maintain the correct order of the events. Then we call the apply method which will make the state change to the aggregate root. And finally we will add this domain event to the internal list of applied events. This is very similar with the dirty check of NHibernate (the idea, not the actual implementation).
This is all what what is needed to execute domain behavior and keep track of the domain events that have been used to update internal state of an aggregate root.
Getting the state changes
So now we have build up some internal state changes and we want to persist them to some sort of medium. I am not going to discuss how to actually persist these state changes, that is for a later post, all I want to show you now is how to get them out of the aggregate root. How about we start with the method GetChanges
1 IEnumerable<IDomainEvent> IEventProvider.GetChanges()
2 {
3 return _appliedEvents
4 .Concat(GetEntityEvents())
5 .OrderBy(x => x.Version)
6 .ToList();
7 }
8
9 private IEnumerable<IDomainEvent> GetEntityEvents()
10 {
11 return _entityEventProviders
12 .SelectMany(entity => entity.GetChanges());
13 }
Here we simply return all the applied domain events, by tracking these domain events we in effect track all the state changes that have happened since the aggregate root was instantiated. Here we also request all the applied domain events from all entities. Than new order the domain events by version. After having received and processed all the applied domain events we should Clear the aggregate root from all applied domain events so they won’t be persisted again.
1 void IEventProvider.Clear()
2 {
3 _entityEventProviders.ForEach(x => x.Clear());
4 _appliedEvents.Clear();
5 }
Just a quick word about the entity event providers, in some cases you want to have domain behavior inside entities that are part of the aggregate but are not the aggregate root. Well in this case you want to have those entities generate domain events as well, and you want to get those as well when getting all changes. Same when clearing the domain also the changes inside each entity event provider should be cleared.
Before saving the changes in the aggregate root is finalized we also need to update the version of the aggregate root. This version will match the version of the last applied domain event.
Loading historical domain events
In a next post I’ll dig deeper into the event store but for now lets just assume you have a very nice way of storing these domain events and have the ability to retrieve them again.
As the IEventProvider interface nicely dictates there is a LoadFromHistory method that takes an IEnumerable<IDomainEvent> below here is the implementation of this method.
1 void IEventProvider.LoadFromHistory(IEnumerable<IDomainEvent> domainEvents)
2 {
3 if (domainEvents.Count() == 0)
4 return;
5
6 foreach (var domainEvent in domainEvents)
7 {
8 apply(domainEvent.GetType(), domainEvent);
9 }
10
11 Version = domainEvents.Last().Version;
12 EventVersion = Version;
13 }
When you take a look in the for each loop you will notice that here we are calling apply again, please note that this is the private variant which is responsible for updating the internal state of the aggregate root and that these events are not added to the _appliedEvents collection, nor is the Id or Version updated. We don’t want to save these events again. After applying all the historical domain events we update the aggregate root version to the version of the last event.
The base class
I am using a base class to provide this functionality to all the different aggregate roots using inheritance and I know there are different opinions about this. So I wanted to highlight that you can achieve the same results by using composition. Your aggregate roots still need to implement the interfaces, but the implementation can be provided by using composition.
An other thing is that all the public methods in the BaseAggregateRoot are explicate interface implementation. I do this because I want to hide these details for any piece of code that is using the aggregate root as is, only when dealing with persistence we use the interface and get access to the explicit interface methods. Nice and clean.
Aggregate entities
Ok I have already mentioned the term entities and entity event providers, and I would like to focus on them for a bit. An entity is an domain object that is part of the same aggregate as the aggregate root, but is not the aggregate root it self, is however it is managed by the aggregate root. We manage state changes in these entities in the exact same way as we do this in the aggregate root, so each entity is also an event provider. There is a different interface for the entities then for the aggregate root so they can not be confused among each other.
1 namespace Fohjin.DDD.EventStore
2 {
3 public interface IEntityEventProvider
4 {
5 void Clear();
6 void LoadFromHistory(IEnumerable<IDomainEvent> domainEvents);
7 void HookUpVersionProvider(Func<int> versionProvider);
8 IEnumerable<IDomainEvent> GetChanges();
9 Guid Id { get; }
10 }
11 }
You may have also noticed the hookup version provider method, remember it
The problem is that we should deal with the whole aggregate as a whole so all state changes need to be persisted within the same transaction. So we want to have a single point to access the internal state of the whole aggregate as well as a single point to load the history back into the whole aggregate. In order to achieve this the aggregate root needs to register all the entity event providers so it can track them. To enable that we have an additional interface for our aggregate root to implement.
1 namespace Fohjin.DDD.EventStore
2 {
3 public interface IRegisterEntities
4 {
5 void RegisterEntityEventProvider(IEntityEventProvider entityEventProvider);
6 }
7 }
Lets look at the implementation right away
1 void IRegisterEntities.RegisterEntityEventProvider(IEntityEventProvider entityEventProvider)
2 {
3 entityEventProvider.HookUpVersionProvider(GetNewEventVersion);
4 _entityEventProviders.Add(entityEventProvider);
5 }
Now this is only a very simple collection that hold references to IEntityEventProviders which is used in the previous shown GetEntityEvents method. So getting out the changes is relatively simple this way. I also created a special collection that will automatically register entities when they are added to the collection.
Remember I mentioned the HookUpVersionProvider method, well this is used to get a reference to the method from the aggregate root that deals with assigning a new version to each event. We want a reference to the same version generator that the aggregate root uses because then all the versions of each domain event will be in sequence independently is the aggregate root or an entity created it.
1 namespace Fohjin.DDD.Domain
2 {
3 public class EntityList<TEntity> : List<TEntity> where TEntity : IEntityEventProvider
4 {
5 private readonly IRegisterEntities _aggregateRoot;
6
7 public EntityList(IRegisterEntities aggregateRoot)
8 {
9 _aggregateRoot = aggregateRoot;
10 }
11
12 public new void Add(TEntity entity)
13 {
14 _aggregateRoot.RegisterEntityEventProvider(entity);
15 base.Add(entity);
16 }
17 }
18 }
The collection takes a reference to the aggregate root it is part of in the constructor to be able to add each added entity event provider to the collection in the aggregate root.
Currently there is some duplication between the BaseAggregateRoot and the BaseEntity because they are inherited from different interfaces, I am sure there is some optimization possible there
There is finally one more thing to cover about this and that is how historical domain events are being passed into the correct entity, currently this is a bit ugly but I am working on a more elegant solution. Take a look at the code.
1 private void registerEvents()
2 {
3 // Registration of Aggregate Root event handlers
4
5 RegisterEvent<BankCardWasReportedStolenEvent>(onAnyEventForABankCard);
6 RegisterEvent<BankCardWasCanceledByCLientEvent>(onAnyEventForABankCard);
7 }
8
9 private void onAnyEventForABankCard(IDomainEvent domainEvent)
10 {
11 IEntityEventProvider bankCard;
12 if (!_bankCards.TryGetValueById(domainEvent.AggregateId, out bankCard))
13 throw new NonExistingBankCardException("The requested bank card does not exist!");
14
15 bankCard.LoadFromHistory(new[] { domainEvent });
16 }
So each entity domain event will be registered here as well and are all passed to one specific event handler (one specific event handler for each different entity type). What happens is that we check if the specific event provider is present in the collection by looking for the Id, when the requested event provider is found the historical domain event will be loaded using the load from history method on the event provider.
The problem here is that the information which events the entity can produce is already registered, and that is in the entities them self’s. So by making that information statically available I should be able to auto register the entity event handlers.
Finally
I hope that this was a useful explanation of how the aggregate root works with the internal domain events, and that you would agree with me that it really is not very difficult. Next time I want to discuss the event store so we can take a look at persisting the domain events. I will also post a blog about making the entity registration more elegant and less manual work.
Tags: Architecture, CQRS, DDD
Posted by Mark Nijhof on Nov 11, 2009 in
- Dotnet |
View Original Article
This post was originally posted on my previous blog: blog.fohjin.com.
I have had the pleasure of spending a 2 day course and many geek beers with Greg Young talking about Domain-Driven Design specifically focused on the Command and Query Responsibility Segregation (CQRS) pattern. Greg has taken Domain-Driven Design from how Eric Evans describes it in his book and has adapted mostly the technical implementation of it. Command Query Separation (CQS) was originally thought of by Bertrand Meyer and is applied at object level.
CQS: “every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer”
-Bertrand Meyer
Greg however takes this same principle but he applies it to the whole architecture of a system, clearly separating the write side (Commands) from the read side (Queries) of the system. The write side is what we already know as the domain, containing all the behavior which is what makes the system valuable. The read side is specialized towards the specific reporting needs, think for example about the application screens that enables the users to execute domain behavior, but also any traditional reporting needs are provided by the read database.
So lets take a quick look at the overall architecture before we dive into the details:
Command and Query Responsibility Segregation (CQRS) – Overview
You have to excuse me for not using Visio to make this drawing, but I really didn’t feel like tackling yet an other layer of complexity tonight. At least I did the labels in typed text, so it is readable. I will discuss this architecture in 4 phases, the order I choose is what I believe is the natural way your would think about this. In the end you will see that the whole principle is rather simple. Really.
Command and Query Responsibility Segregation (CQRS) – Division
-
Queries
-
Commands
-
Internal Events
-
External Events (Publishing)
In order to understand this type of architecture better I decided to build an example application; I will use this example in this post to demonstrate the different aspects of the architecture to you. The example has already been released in the wild (ok I meant the DDD group on Yahoo) and can be found here:http://github.com/MarkNijhof/Fohjin
Queries (reporting)
The first part I would like to discuss is the reporting needs of a system, Greg defines any need for data from the system as a reporting need; this includes the various application screens which the user uses to base his decisions on. This seemed like a strange statement at first, but the more I think about it the more sense it makes. This data is purely used to inform the user (or other systems) about the current state of the system in the specific context of the user so that they can make certain decisions and execute domain behavior.
These reports will never be updated directly by the consumer of these reports, the data represents the state of the domain, so the domain is responsible for updating it. So all we really do on this side is report the current state of the system to who or what ever needs it.
When an application is requesting data for an specific screen than this should be done in one single call to the Query layer and in return it will get one single DTO containing all the needed data. Now because of this specific use of the data it makes sense to order and group it in such a way that is determined by the needs of the system. So we de-normalizing the data trying to make a single table reflect a single screen or usage in the client application. The reason for this is that data is normally queried many times more than domain behavior is being executed, so by optimizing this you will enhance the perceived performance of the system.
Here you may choose to use an ORM like NHibernate to facilitate the reading from the database, but considering that you would only be using a very small percentage of the capabilities of a proper ORM you may not need to go that way at all. Maybe going for Linq2Sql of even as Greg suggested using reflection to assemble the SQL statements directly from the DTO’s (using reflection and Convention over Configuration makes this rather simple) is perhaps a better solution for the problem. This will be up to you and probably depends on specific scenario and what you feel comfortable with.
In the example that I created to demonstrate this type of architecture I choose for using reflection of the DTO’s because I wanted to put the emphasis on the CQRS implementation and not on the ORM implementation.
The more traditional reporting needs will also get its own database schema and the data there will be optimized for that need as well, so in the end we will end up with quite a bit of duplication of the data, but that is all right. The process that is responsible for updating the data in the different databases will make sure that this happens in the correct way, we will go over this in a later part of this post.
Commands (executing behavior on the domain)
Lets first consider what would normally happen after receiving a DTO; the user would make changes to the data and save this back on the DTO. This DTO then gets shipped back to the back-end, converted into an entity and the ORM will make sure that the changes are persisted into the database.
This would result in loosing some very valuable information; the Why did this change happen? You completely loose the intent the user had when he changed the data, and this is one of the things Greg’s implementation of CQRS is solving.
CQRS as the name indicates uses Commands, these commands are created on the client application and then send to the Domain layer. Lets take an example: A customer from a bank comes in the office and tells the person behind the desk that he needs to change his address. And instead of just getting the customer information and making the changes directly in the address fields, the bank employee firsts asks the question; Why would you want to change your address? The most likely response would be because the customer has moved, but it could also be because there is an error in his address and that all his mail ends up with his downstairs neighbor. Now these are two completely different reasons to update a customer address. Why could this be important? Well granted the example is rather silly, but lets assume the bank wants to know how many customers go to a competitor after moving? How loyal are our customers, should we keep sending them specific information after they have moved x miles away? Right this information is completely lost in our original way of working, but when using commands and events (more on events later) we maintain the original intent of the action. So after asking the question the customer answers that he has indeed moved and the bank employee selects the “Customer has moved" in the application and gets the ability to change only the address. When clicking save a CustomerMovedCommand will be created with only the changed address and is send to the domain.
We also get one other great benefit from using these commands and that is that these commands are easy to communicate with our client while building or working on the system. Because our clients would most likely use these types of behavior when explaining what they want to accomplish. Al do Greg thinks times have changed, “Our grand failure", but it should really be the case that our clients talk their own domain language. When using these commands we can start talking the same language even in the code.
That is what Domain-Driven Design is all about, instead of doing something technical like update client, it is actually describing the process that the user uses into the code like; the client has moved.
Command
1 namespace Fohjin.DDD.Commands
2 {
3 [Serializable]
4 public class ClientIsMovingCommand : Command
5 {
6 public string Street { get; private set; }
7 public string StreetNumber { get; private set; }
8 public string PostalCode { get; private set; }
9 public string City { get; private set; }
10
11 public ClientIsMovingCommand(Guid id, string street, string streetNumber, string postalCode, string city) : base(id)
12 {
13 Street = street;
14 StreetNumber = streetNumber;
15 PostalCode = postalCode;
16 City = city;
17 }
18 }
19 }
All these commands will be send to the Command Bus which will delegate each command to the command handler or command handlers. This also effectively means that there is only one entry point into the domain and that is via the Bus. The responsibility of these command handlers is to execute the appropriate behavior on the domain. Close to all of these command handlers will have the repository injected to provide the ability to load needed the Aggregate Root on which then the appropriate behavior will be executed. Usually only one Aggregate Root will be needed in a single command handler. Later we will also take a closer look at the repository as it is different from your ordinary DDD repository.
Command Handler
1 namespace Fohjin.DDD.CommandHandlers
2 {
3 public class ClientIsMovingCommandHandler : ICommandHandler<ClientIsMovingCommand>
4 {
5 private readonly IDomainRepository _repository;
6
7 public ClientIsMovingCommandHandler(IDomainRepository repository)
8 {
9 _repository = repository;
10 }
11
12 public void Execute(ClientIsMovingCommand compensatingCommand)
13 {
14 var client = _repository.GetById<Client>(compensatingCommand.Id);
15
16 client.ClientMoved(new Address(compensatingCommand.Street, compensatingCommand.StreetNumber, compensatingCommand.PostalCode, compensatingCommand.City));
17 }
18 }
19 }
As you can see a command handler has only one responsibility and that is to handle the one particular command by executing the appropriate domain behavior. The command handler should not be doing any domain logic itself. If there is a need for this than that logic should be moved into a service of its own. An example of this is in my example code is an incoming money transfer, more about that later.
Internal Events (capturing intent)
So finally we have arrived at the actual domain, the client has requested a certain view of our domain, has received the appropriate report DTO and has made a decision which resulted into a command being published. The appropriate command handler has then loaded the correct Aggregate Root and executed the appropriate domain behavior. So now what?
Now we are going to separate the domain behavior from the state changes resulting from this domain behavior including the triggering of external behavior. This would not be much different from how you would do this now, first verify the normal guards, do what you have to do, but don’t set any internal state, and don’t trigger any external behavior (Ok the last part is more an optional thing to consider, state is the key here). Instead of writing these state changes directly to the internal variables you create an event and fire it internally. This event as well as the method name of the behavior should be descriptive in the Ubiquitous Language of the domain. Then the event will be handled inside the domain Aggregate Root which will set the internal state to the correct values. Remember that the event handler should not be doing any logic other then setting the state, the logic should be in the domain method.
Domain Behavior
1 public void ClientMoved(Address newAddress)
2 {
3 IsClientCreated();
4
5 Apply(new ClientMovedEvent(newAddress.Street, newAddress.StreetNumber, newAddress.PostalCode, newAddress.City));
6 }
7
8 private void IsClientCreated()
9 {
10 if (Id == Guid.Empty)
11 throw new NonExistingClientException("The Client is not created and no opperations can be executed on it");
12 }
Domain Event
1 namespace Fohjin.DDD.Events.Client
2 {
3 [Serializable]
4 public class ClientMovedEvent : DomainEvent
5 {
6 public string Street { get; private set; }
7 public string StreetNumber { get; private set; }
8 public string PostalCode { get; private set; }
9 public string City { get; private set; }
10
11 public ClientMovedEvent(string street, string streetNumber, string postalCode, string city)
12 {
13 Street = street;
14 StreetNumber = streetNumber;
15 PostalCode = postalCode;
16 City = city;
17 }
18 }
19 }
Internal Domain Event Handler
1 private void onNewClientMoved(ClientMovedEvent clientMovedEvent)
2 {
3 _address = new Address(clientMovedEvent.Street, clientMovedEvent.StreetNumber, clientMovedEvent.PostalCode, clientMovedEvent.City);
4 }
The reason why we want these events is because they now become part of our persistence strategy, meaning that the only information we will be persisting of an Aggregate Root are the generated events. So if every state change is triggered by an event, and an internal event handler has no other logic then setting the correct state (and that means not even deriving other information from the data in the event), then what we can do then is load all historical events and have the Aggregate Root replay them all internally bringing back the original state of the Aggregate Root in exactly the same way it got there in the first place. It really is the same as replaying a tape.
One thing to note is that these events are write only, you will never add, alter or remove an event. So if you suddenly end up with a bug in your system which is generating wrong events, then the only way for you to correct this is to generate a new compensating event correcting the results of the bug. Of course you want to fix the bug as well. This way you have also tracked when the bug was fixed and when the effects of the bug where corrected.
By having this architecture we now basically solved the problem of loosing original intent, because we keep all events that have ever happened and these evens are intent revealing. An other very interesting thing is that now you have an audit log for free, because nothing will ever change state without an event and the events are stored and used in building up the Aggregate Roots they are guaranteed in sync with each other.
The Domain Repository
I mentioned before that the Domain Repository would be completely different from one that is normally the result of practicing DDD. Normally you would end up with very specific repositories allowing the request of all kinds of different information from the domain. But when using Greg’s implementation of CQRS your domain is completely write only, so the repository only has to be able to Get an Aggregate Root by its Id and it must be able to save the generated events. You also completely get rid of any impedance mismatch between the domain and the persistence layer.
Domain Repository Contract
1 namespace Fohjin.DDD.EventStore
2 {
3 public interface IDomainRepository
4 {
5 TAggregate GetById<TAggregate>(Guid id)
6 where TAggregate : class, IOrginator, IAggregateRootEventProvider, new();
7
8 void Add<TAggregate>(TAggregate aggregateRoot)
9 where TAggregate : class, IOrginator, IAggregateRootEventProvider, new();
10 }
11 }
The reporting repositories on the other hand would probably look much more like the traditional repositories from DDD.
So what happens when you have 100.000 events that need to be replayed every-time you load the Aggregate Root, that will slow down your system immensely. So to counter this effect you would use the Memento pattern to take a snapshot from the internal state of the Aggregate root every x number of events. Then the repository will first request the snapshot, load that in the Aggregate Root and then request all the events that have occurred after the snapshot, bringing it back to the original state. This is only an optimization technique you would not delete events that happened before the snapshot, that would pretty much defeat the purpose of this architecture.
Data Mining
One other really interesting fact about storing all the events is that you can replay these events at a later date and retrieve important business information from them. And you get this information from the start of the system, instead having to build-in some extra logging and wait a few months for reliable data.
External Events (publishing, letting others know)
Finally we are getting to the fourth part of this explanation (and I am saying this more for my own sake, pfff). So what happens here, looking back at what we have so far, we can read domain state and we can execute behavior and update the internal state of the domain. The obvious thing that is missing is a way to bring the reporting database in sync with the current state of the domain. The way we will be doing this is by publishing the internal domain events outside the domain. Then there are event handlers that pick up on those events and bring the reporting database in sync. This is a place where you could use an ORM, but in fact it is very easy to just generate the needed SQL statements and execute them.
Greg actually mentioned a really nice way of caching these SQL statements, he would batch them in a single batch and execute the batch if it gets older then x seconds, or (and this is the interesting part) whenever a read request came in. So when a read request comes in this SQL statement is appended to the batch and the whole thing is executed, ensuring that the read request will always have the latest data available to that part of the system. More on this below here.
The domain repository is responsible for publishing the events, this would normally be inside a single transaction together with storing the events in the event store.
Events are also used to communicate between different Aggregate Roots, I my example I am using a transaction from one account to an other account. Here I generate an event that money is being transferred to an other account, this event will reduce the balance of the current account. Later an event handler will make the same change in the reporting database. An other event handler will actually forward the transaction to a service which checks if the target account is a local account, else forwards a money transfer to a different bank (in my example the different bank is actually the same, but via a different route). But lets assume that the money transfer goes to an internal account, in that case the service will publish a money transfer received command in the command bus and the whole process continues in a different Aggregate Root. So in this case the command is not triggered from a GUI but from a different part in the system.
There is an other interesting fact in the scenario when money is received from an other bank, because a money transfer only has the account number to identify the target account and not the Aggregate Root Id (you can’t expect foreign systems to know this, yes I know you can make this a natural Id as well) the money received service first needs to do a query to the reporting database requesting an account DTO where the account number is the same as the target account. When this is successful it will use the Id from the account DTO and put that in the command to be published.
But it doesn’t stop there, as I mentioned before you could also have events that don’t have any state change information but for example indicate that a message (Email, SMS or what ever, depends on the event handler) needs to be send to an user. And because you are using Domain Events for all this, everything will be stored in the Event Store, so you keep your history.
Eventual Consistency
Normally when beginning to implement CQRS you would start with a direct publishing mechanism so that storing the events and updating the reporting database happen in the same thread. When using this approach you have no problems with eventual consistency.
But when you system starts to grow you might get some performance problems and then you could start by implementing a bus disconnecting the publishing of the events and handling of these events. This means that it is possible and likely that your event store and reporting database are not completely in sync with each other, they are eventual consistent. Which means that it is possible that the user sees old data on his screens.
Depending on how critical this really is you can have different counter measures for this, which I will be going into in a different post as this is also not something the example provides.
Specifications
The specifications that you can write using this architecture is something that I really like, what you would do is talk to your client and ask him things about how he wants his process to work. So a possible scenario could be:
Withdrawing money from an account
So how would that go? Well the clients needs to have opened an account with our bank and he needs to have some money transferred on it in order to be able to withdraw money from it. And when this happens the balance of the account must be lowered to the correct amount. Ok so, given an account was opened, and a cash was deposited, when making a cash withdraw then we get a cash withdrawn event.
1 namespace Test.Fohjin.DDD.Scenarios.Withdrawing_cash
2 {
3 public class When_withdrawing_cash : CommandTestFixture<WithdrawlCashCommand, WithdrawlCashCommandHandler, ActiveAccount>
4 {
5 protected override IEnumerable<IDomainEvent> Given()
6 {
7 yield return PrepareDomainEvent.Set(new AccountOpenedEvent(Guid.NewGuid(), Guid.NewGuid(), "AccountName", "1234567890")).ToVersion(1);
8 yield return PrepareDomainEvent.Set(new CashDepositedEvent(20, 20)).ToVersion(1);
9 }
10
11 protected override WithdrawlCashCommand When()
12 {
13 return new WithdrawlCashCommand(Guid.NewGuid(), 5);
14 }
15
16 [Then]
17 public void Then_a_cash_withdrawn_event_will_be_published()
18 {
19 PublishedEvents.Last().WillBeOfType<CashWithdrawnEvent>();
20 }
21
22 [Then]
23 public void Then_the_published_event_will_contain_the_amount_and_new_account_balance()
24 {
25 PublishedEvents.Last<CashWithdrawnEvent>().Balance.WillBe(15);
26 PublishedEvents.Last<CashWithdrawnEvent>().Amount.WillBe(5);
27 }
28 }
29 }
Ok ok, but now we have the same story, only now there is not enough money on the account, then we should give an exception.
1 namespace Test.Fohjin.DDD.Scenarios.Withdrawing_cash
2 {
3 public class When_withdrawling_cash_from_an_account_account_with_to_little_balance : CommandTestFixture<WithdrawlCashCommand, WithdrawlCashCommandHandler, ActiveAccount>
4 {
5 protected override IEnumerable<IDomainEvent> Given()
6 {
7 yield return PrepareDomainEvent.Set(new AccountOpenedEvent(Guid.NewGuid(), Guid.NewGuid(), "AccountName", "1234567890")).ToVersion(1);
8 }
9
10 protected override WithdrawlCashCommand When()
11 {
12 return new WithdrawlCashCommand(Guid.NewGuid(), 1);
13 }
14
15 [Then]
16 public void Then_an_account_balance_to_low_exception_will_be_thrown()
17 {
18 CaughtException.WillBeOfType<AccountBalanceToLowException>();
19 }
20
21 [Then]
22 public void Then_the_exception_message_will_be()
23 {
24 CaughtException.WithMessage(string.Format("The amount {0:C} is larger than your current balance {1:C}", 1, 0));
25 }
26 }
27 }
The cool part here is that the whole domain is seen as a black box, you are bringing it to a certain state exactly the same way as it is used, then you publish a command just like your application would, and after that you verify that the domain publishes the correct events and that their values are correct. This means that you are never testing your domain in a state that it cannot naturally get to, which makes the tests more reliable.
Now imagine a parser that takes all the class names, underneath each class name it would print the events that occurred to get into the current state. Then you print the command that we are testing. and finally you print the method names that test the actual outcome. This would be a very nice readable specification that the client at least can understand.
Some other benefits
One last benefit I would like to highlight from using this type of architecture is how easy it is to split the work load between different team, more specifically between team with different hourly rates. The domain logic is something that needs to be right, this is where you would put your more expensive developers on, the ones that understand the business, understand good coding practices, you know what I mean. But the read side is not as important, sure it needs to be correct as well, but this is not where the value lies, this can be done quickly and in a year or two again. This is something you let the cheaper developers create, it doesn’t require much domain knowledge all that is really important is that they need to know how the GUI needs to work, what commands they can use and what events to expect.
I think this is of great value for the business, something that is easily overlooked.
Finally
As you can see this is all very simple and straightforward. It is a different mindset, but once you enter this mindset you will notice that your applications will be much more behavioral versus CRUD. And hopefully our clients can move back into thinking about their business logic instead of the thinking about the CRUD way we have forced upon them. Also I would like to thank Greg Young for providing me with so much information and putting up with all my weird questions, and thank Jonathan Oliver and Mike Nichols for some improvements on the technical side.
Tags: Architecture, CQRS, DDD