Building a simple website using Ncqrs
We also offer a screencast if you don’t like text: Screencast – building a website with Ncqrs
Prerequisites
You need the following
- Visual Studio .NET 2010 professional or higher
- Microsoft SQL Server 2008 express or higher
Attachments
There are a few attachments that you need during the this guide.
The result
At the end of this quick start, you should have a simple system that allows users to post messages on a public timeline of a website; see it as a very minimized version of twitter.com. The system contains all the main components of a CQRS based architecture: Command Service, Command Executors, Commands, Domain, Events, Read Model and a User Interface.

Download and install the Ncqrs Framework
For now, use the release from the Attachment section. This getting-started guide walks ahead of the current release!
First you need to install the Ncqrs Framework. You can obtain the Ncqrs framework from the download page at the Codeplex project: http://ncqrs.codeplex.com/releases. There are three packages: the Ncqrs framework itself, the extension to the framework and the sample application. In this case we only need the Ncqrs Framework itself. After you downloaded the release you should unpack the archive into a logic folder, for example “c:\SharedLibraries\Ncqrs\”. That’s it, installation complete. Now it is time to do some coding so grab some coffee and fire up Visual Studio!
Create a new solution
Fire up Visual Studio 2010 and create a new blank solution with the name “SimpleTwitter”. This will be the solution that will contain all the projects that form our system.
Add a new Domain project
It is time for the first component of our system; the domain. This will be the hearth of our system that contains the model that focuses on transactional behavior. Add a new Class Library project with the name “Domain” and remove the default “class1.cs” file. Add a reference to Ncqrs.dll that is in the folder where you extracted the release. Create a new class “Tweet” that subclasses the Ncqrs.Domain.AggregateRootMappedByConvention class. This aggregate root represents the concept of a message on our public timeline. Add three private members: string _message, string _who, DateTime _timestamp. The final code should look like this:
using System;
using Ncqrs.Domain;
namespace Domain
{
public class Tweet : AggregateRootMappedByConvention
{
private string _message;
private string _who;
private DateTime _timestamp;
}
}
Add a new Events project
All state transitions in aggregate roots are done via events. So before we add logic to initialize the Tweet aggregate we should add a event that represents this transition (the creation of a tweet). Add a new Class Library project and name it “Events”. Add a reference to Ncqrs.dll. Add a new class and name it “TweetPostedEvent” that subclasses the Ncqrs.Domain.DomainEvent class. Add three public properties: string Message , string Who, DateTime TimeStamp. Also annotate the class as serializable by adding the SerializableAttribute on top of it. The final code should look like this:
using System;
using Ncqrs.Domain;
namespace Events
{
[Serializable]
public class TweetPostedEvent : DomainEvent
{
public string Message { get; set; }
public string Who { get; set; }
public DateTime TimeStamp { get; set; }
}
}
Add a reference from the Domain project to the Events project so we can use the TweetPostedEvent within the Tweet aggregate.
Initialize the Tweet aggregate root
We have defined an event object that can represents the posting of a tweet. Now it is time to add logic to initialize the Tweet aggregate root. To do so, add a public constructor to the Tweet aggregate root that accepts two parameters: message : string, who : string. Create a new Events.TweetPostedEvent object within the body of the constructor based on the values of the parameters and use DateTime.UtcNow for the TimeStamp property. Call the ApplyEvent method and pass the event object as the first parameter. The final code should look like this:
using System;
using Ncqrs.Domain;
using Events;
namespace Domain
{
public class Tweet : AggregateRootMappedByConvention
{
private string _message;
private string _who;
private DateTime _timestamp;
public Tweet(string message, string who)
{
var e = new TweetPostedEvent
{
Message = message,
Who = who,
TimeStamp = DateTime.UtcNow
};
ApplyEvent(e);
}
}
}
Adding a event handler
The ApplyEvent method causes the event to be temporarily stored and invokes the event handler that handled this event. Event handlers in this context are methods on an aggregate root that update the state of the object with the information from the event. Since we subclass from the AggregateRootMappedByConvention class we can create event handlers very easily by satisfying a certain convention. Add a void method with the name OnTweetPosted that accepts one parameter TweetPostedEvent event. Within the method body update the three private fields with the values from the event object. The final code should look like this:
using System;
using Ncqrs.Domain;
using Events;
namespace Domain
{
public class Tweet : AggregateRootMappedByConvention
{
private string _message;
private string _who;
private DateTime _timestamp;
public Tweet(string message, string who)
{
var e = new TweetPostedEvent
{
Message = message,
Who = who,
TimeStamp = DateTime.UtcNow
};
ApplyEvent(e);
}
protected void OnTweetPosted(TweetPostedEvent e)
{
_message = e.Message;
_who = e.Who;
_timestamp = e.TimeStamp;
}
}
}
Adding a new Command project
We now have a domain where we can create a new tweet and a event object that can represent that state transition. Now we need to add a command to our system that allows other components like a user interface or a external system to make modifications to our system. Start by create a new Class Library project and name it “Commands”. Remove the default “Class1.cs” file from the project and add a reference to Ncqrs.dll. Add a new class and name it PostNewTweetCommand. Subclass the Ncqrs.Commanding.CommandBase class and add two public properties: string Message, string Who. The final code should look like this:
using System;
using Ncqrs.Commanding;
namespace Commands
{
public class PostNewTweetCommand : CommandBase
{
public string Message { get; set; }
public string Who { get; set; }
}
}
Adding a new Command Executor project
Since we now have a command, we should have an object that can execute it. Executing it means making modifications on the domain based on the command. Add a new Class Library project and name it “CommandExecutors”. Remove the “Class1.cs” file from the project and add a reference to Ncqrs.dll. Also add a reference to the Commands project and the Domain project. Add a new class and name it “PostNewTweetCommandExecutor”. Subclass from Ncqrs.Commanding.CommandExecution.CommandExecutorBase<Commands.PostNewTweetCommand>. Implement this abstract class by overriding the protected void ExecuteInContext method. Within this method create a new Tweet object from the domain with the value from the command. And add a call to the Accept() method on the context variable. The final code should look like this:
using System;
using Ncqrs.Commanding.CommandExecution;
using Commands;
using Ncqrs.Domain;
using Domain;
namespace CommandExecutors
{
public class PostNewTweetCommandExecutor : CommandExecutorBase<PostNewTweetCommand>
{
protected override void ExecuteInContext(IUnitOfWorkContext context, PostNewTweetCommand command)
{
var newTweet = new Tweet(command.Message, command.Who);
context.Accept();
}
}
}
Adding a new Command Service project
We have a command and a corresponding executor, now it is time to create a command service the hosts. We will use WCF for this. Create a new WCF Service Application and name it “CommandService”. Remove the default “IService1.cs” and “Service1.csv” files. Add a reference to Ncqrs.dll and to the projects Commands and CommandsExecutors. Add a new WCF Service by right clicking on the CommandService item in the solution explorer and choose for “Add->New Item…”. A new dialog appears and look for the WCF Service item template and insert “SimpleTwitterCommandService” in the name textbox. Hit the Add button and two items are added to the project: ISimpleTwitterCommandService.cs and SimpleTwitterCommandService.svc.
Defining the correct service interface
Open the ISimpleTwitterCommandService.cs file rename the DoWork method to Execute and add one parameter command of the type Commands.PostNewTweetCommand. The final code should look like this:
using System;
using System.ServiceModel;
using Commands;
namespace CommandService
{
[ServiceContract]
public interface ISimpleTwitterCommandService
{
[OperationContract]
void Execute(PostNewTweetCommand command);
}
}
Implementing the service interface
Dubbelclick on the SimpleTwitterCommandService.svc item to go to the service implementation. Remove the DoWork method and implement the ISimpleTwitterCommandService interface. In the Execute method body create a local variable service and use the Ncqrs.NcqrsEnvironment.Get<ICommandService>() method to initialize it. Now pass the command parameter to the Execute method on the service variable. The final code should look like this:
using System;
using Ncqrs;
using Ncqrs.Commanding.ServiceModel;
using Commands;
namespace CommandService
{
public class SimpleTwitterCommandService : ISimpleTwitterCommandService
{
public void Execute(PostNewTweetCommand command)
{
var service = NcqrsEnvironment.Get<ICommandService>();
service.Execute(command);
}
}
}
Bootstrapping the Ncqrs environment
We should now setup the environment so the the Ncqrs.NcqrsEnvironment.Get<ICommandService>() call actually give the result we want. Add a new class to the CommandService project and name it “Bootstrapper”. Make the class public and static. Add a new private static void InitializeCommandService() method. In the method body initialize a local variable service as a new Ncqrs.Commanding.ServiceModel.InProcessCommandService. Register a new CommandExecutors.PostNewTweetCommandExecutor with the RegisterExecutor method. The final code should look like this:
using System;
using Ncqrs.Commanding.ServiceModel;
using CommandExecutors;
namespace CommandService
{
public static class Bootstrapper
{
private static ICommandService InitializeCommandService()
{
var service = new InProcessCommandService();
service.RegisterExecutor(new PostNewTweetCommandExecutor());
return service;
}
}
}
BootUp with the BootStrapper
Add a new public static void BootUp() method to the Bootstrapper class. Within this method use the SetDefault<ICommandService> method of the Ncqrs.NcqrsEnvironment class with the result of the InitializeCommandService method to set the default command service. The final code should look like this:
using System;
using Ncqrs.Commanding.ServiceModel;
using CommandExecutors;
using Ncqrs;
namespace CommandService
{
public static class Bootstrapper
{
public static void BootUp()
{
NcqrsEnvironment.SetDefault<ICommandService>(InitializeCommandService());
}
private static ICommandService InitializeCommandService()
{
var service = new InProcessCommandService();
service.RegisterExecutor(new PostNewTweetCommandExecutor());
return service;
}
}
}
Calling the boostrapper from the SimpleTwitterCommandService
Go to the SimpleTwitterCommandService class in the CommandService project. Add a static constructor and within that constructor call the Bootstrapper.BootUp method. The final code should look like this:
using System;
using Ncqrs;
using Ncqrs.Commanding.ServiceModel;
using Commands;
namespace CommandService
{
public class SimpleTwitterCommandService : ISimpleTwitterCommandService
{
static SimpleTwitterCommandService()
{
Bootstrapper.BootUp();
}
public void Execute(PostNewTweetCommand command)
{
var service = NcqrsEnvironment.Get<ICommandService>();
service.Execute(command);
}
}
}
Adding a new User Interface project
Add a new ASP.NET MVC 2 Web Application and name it “UserInterface”. When asked to create a unit test project shooce “No”.

Add a reference to Ncqrs.dll and to the Commands project. Now build the whole solution and add a service reference to the CommandService project. Do so by right clicking the References item in the command project in the Solution Explorer and choose for “Add Service Reference…”. Hit the “Discover” button and choose for the SimpleTwitterCommandService. In the Namespace textbox enter “Commanding” and hit “Ok”.

Adding the TweetController
Right click the Controllers folder in the UserInterface project and choose for “Add->Controller…”. In the dialog enter the name “TweetController” and hit “Ok”. A new class TweetController is added to the project. Within this class add a public method with the name “Add” that returns a empty ActionResult instance. Also add a new public method with the name “Add” that accepts one Command.PostNewTweetCommand parameter. Annotate the method with the HttpPostAttribute. Within the method body create a local variable service and initialize this with a new Commanding.SimpleTwitterCommandServiceClient. Call the Execute method on the service variable and pass the command parameter as the first argument. Now add a statement that returns the result of a call to the View method. The final code should look like this:
using System;
using System.Web.Mvc;
using UserInterface.Commanding;
using Commands;
namespace UserInterface.Controllers
{
public class TweetController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Add()
{
return View();
}
[HttpPost]
public ActionResult Add(PostNewTweetCommand command)
{
var service = new SimpleTwitterCommandServiceClient();
service.Execute(command);
return View();
}
}
}
Adding the Add view
Now since we have a controller with Add actions we should add a view. In the Views folder of the UserInterface project add a new folder called “Tweet” and add a new view to it by right clicking that folder an choose for “Add->View…”. Name the view “Add” and check the “Create a strongly-typed view”. Choose the Commands.PostNewTweetCommand as View data class and choose for the “Create” template as View content.

Open the Site.Master file from the “Views\Shared” folder in the UserInterface project. Add a new menu item in by changing the html of the ul-tag around line 24 to the following code:
<ul id="menu">
<li><%: Html.ActionLink("Home", "Index", "Home")%></li>
<li><%: Html.ActionLink("Post New", "Add", "Tweet")%></li>
<li><%: Html.ActionLink("About", "About", "Home")%></li>
</ul>
Adding sql event store database
Grab the EventStore.mdf database from the attachments section and store it somewhere locally. Now in the solution explorer right click the App_Data folder in the CommandService project and choose “Add->Existing Item…”. Browse to the EventStore.mdf database file and hit “Ok”. The EventStore.mdf file should now be visable in the App_Data folder.
Using EventStore.mdf as the event store
Open the Bootstrapper class in the CommandService project. Add a new static method to it and call it InitializeEventStore. As return type use Ncqrs.Eventing.Storage.IEventStore. Within this method return a new instance of the Ncqrs.Eventing.Storage.SQL.SimpleMicrosoftSqlServerEventStore. As connection use the following: “Data Source=.\SQLEXPRESS;Integrated Security=SSPI;User Instance=True;AttachDbFilename=|DataDirectory|\EventStore.mdf;”. In the BootUp method use the Ncqrs.NcqrsEnvironment.SetDefault<IEventStore> method with the result of the InitializeEventStore to set the default event store for the environment.
The final code should look like this:
using System;
using Ncqrs;
using Ncqrs.Commanding.ServiceModel;
using Ncqrs.Eventing.Storage;
using Ncqrs.Eventing.Storage.SQL;
using CommandExecutors;
namespace CommandService
{
public static class Bootstrapper
{
public static void BootUp()
{
NcqrsEnvironment.SetDefault<ICommandService>(InitializeCommandService());
NcqrsEnvironment.SetDefault<IEventStore>(InitializeEventStore());
}
private static IEventStore InitializeEventStore()
{
return new SimpleMicrosoftSqlServerEventStore("Data Source=.\\SQLEXPRESS;Integrated Security=SSPI;User Instance=True;AttachDbFilename=|DataDirectory|\\EventStore.mdf;");
}
private static ICommandService InitializeCommandService()
{
var service = new InProcessCommandService();
service.RegisterExecutor(new PostNewTweetCommandExecutor());
return service;
}
}
}
Verify that the event store is used
Set the UserInterface as the start project of the solution by right clicking it in the solution explorer and choose for “Set as startup project”. Now hit F5 to start debugging. You favorite browser should now launch and display the start page of our website. Click on “Post New “ in the menu at the top right of the site. Enter some random values in the two input fields and hit “Create”. After the post is complete, go back to visual studio and double click the EventStore.mdf file in the App_Data folder of the CommandService project. The Server Explorer pane should pop with an active connection to that database. Expand the “Tables” folder in that pane and right click the Events table. In the context menu choose “Show Table Data”. There should be one row that holds the event data for the tweet that you have just posted.

Add new read model project
Since we are now able to post new tweets in our system, it is time to add the possibility to also viewing them. Therefore we add a new project that will hold the read model. Add a new Class Library project to the solution and name it “ReadModel”. Add a reference to Ncqrs.dll and to the Events project.
Add ReadModel database to it
Grab the ReadModel.mdf database from the attachments section and store it somewhere locally. Now in the solution explorer right click the ReadModel project and choose “Add->Existing Item…”. Browse to the ReadModel.mdf database file and hit “Ok”. The ReadModel.mdf file should now be visible as part of the ReadModel project.
Add LINQ 2 SQL classes mapping
Now since the ReadModel.mdf already contains the read model schema, we use LINQ to SQL Classes. Add a new item to the ReadModel project with the LINQ to SQL Classes template. Right click the ReadModel project in the solution explorer and choose for the LINQ to SQL Classes template as shown in the picture below. As name enter “ReadModel.dbml” and hit the “Add” button.

Map classes
Double click the ReadModel.dbml item in the solution explorer. A new canvas opens where you can create the read model data classes. Now double click the ReadModel.mdf database in the ReadModel project in the solution explorer to open up the Server Explorer with an connection to it. Expand the “Table” folder and drag both the tables to the canvas of the LINQ to SQL classes mapping. The result should look like this the picture below.

The first denormalizer
Now since we have a read model and LINQ to SQL data classes mapped to it we should fill it based on the events. To do so we add denormalizers that make changes to this read model based on events. Add a folder with the name “Denormalizers” to the ReadModel project. We will add one denormalizer for each table in the read model.
Start with adding a new classes with the name TweetListItemDenormalizer. Implement the Ncqrs.Eventing.Denormalization.IDenormalizer<Events.TweetPostedEvent> interface. Within the Handle method, create a local variable context and initialize it with a new ReadModelDataContext instance. Also create local variable newItem and initialize it with a new instance of the TweetListItem. Set the Id property of the newItem instance to the AggregateRootId property from the event. Also set the Message, Who and TimeStamp properties to the values from the event.
Use the InsertOnSubmit method on the TweetListItems property of the context to register the newItem. Now call the SubmitChanges on the context to submit the insert of the TweetListItem. The final code should look like this:
using System;
using Ncqrs.Eventing.Denormalization;
using Events;
namespace ReadModel.Denormalizers
{
public class TweetListItemDenormalizer : IDenormalizer<TweetPostedEvent>
{
public void Handle(TweetPostedEvent evnt)
{
var context = new ReadModelDataContext();
var newItem = new TweetListItem();
newItem.Id = evnt.AggregateRootId;
newItem.Message = evnt.Message;
newItem.Who = evnt.Who;
newItem.TimeStamp = evnt.TimeStamp;
context.TweetListItems.InsertOnSubmit(newItem);
context.SubmitChanges();
}
}
}
Add ReadModel connectionstring to config
We should add a new connection string to the web.config that points to the local database file. Open the web.config in the root of the CommandService project. Now add the following connection string section to it, but with a correct AttachDbFile attribute that contains the path the ReadModel.mdf in the ReadModel project folder:
<configuration>
<connectionStrings>
<add name="ReadModel.Properties.Settings.ReadModelConnectionString"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\pjvds\Documents\visual studio 2010\Projects\SimpleTwitter\ReadModel\ReadModel.mdf;Integrated Security=SSPI;User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<!-- rest of config -->
Setup the event bus
We need to wire up the denormalizers to the eventbus so that they will be called for each event that they are interested in. Add a reference from the CommandService project to the ReadModel project and the Events project. Open the Bootstrapper class and a private static method InitializeEventBus that returns a IEventBus. Within the method create a new instance of the Ncqrs.Eventing.ServiceModel.Bus.InProcessEventBus class and store it in a local variable. Call the RegisterHandler method and pass a new instance of the ReadModel.Denormalizers.TweetListItemDenormalizer. Now return the initialized event bus.
Now set the default for the IEventBus to the result of the InitializeEventBus method in the NcqrsEnvironment. The final code should look like this:
using System;
using Ncqrs.Commanding.ServiceModel;
using Ncqrs;
using Ncqrs.Eventing.Storage;
using Ncqrs.Eventing.ServiceModel.Bus;
using ReadModel.Denormalizers;
using Ncqrs.Eventing.Storage.SQL;
using CommandExecutors;
namespace CommandService
{
public static class Bootstrapper
{
public static void BootUp()
{
NcqrsEnvironment.SetDefault<ICommandService>(InitializeCommandService());
NcqrsEnvironment.SetDefault<IEventStore>(InitializeEventStore());
NcqrsEnvironment.SetDefault<IEventBus>(InitializeEventBus());
}
private static IEventBus InitializeEventBus()
{
var bus = new InProcessEventBus();
bus.RegisterHandler(new TweetListItemDenormalizer());
return bus;
}
private static IEventStore InitializeEventStore()
{
return new SimpleMicrosoftSqlServerEventStore("Data Source=.\\SQLEXPRESS;Integrated Security=SSPI;User Instance=True;AttachDbFilename=|DataDirectory|\\EventStore.mdf;");
}
private static ICommandService InitializeCommandService()
{
var service = new InProcessCommandService();
service.RegisterExecutor(new PostNewTweetCommandExecutor());
return service;
}
}
}
Add index view for tweets
It is time for the last part to close the circle. It is time to add a view that displays all the tweets in the system. From the UserInterface project add a reference to the ReadModel project. Also add a reference to System.Data.Linq. Build the whole solution and right click on the Tweet folder in the UserInterface project. Choose “Add->View…” and enter “Index” as the name for it. Check the “Create a strongly-typed view” box and as View data class choose “ReadModel.TweetIndexItem”. As View content choose the list template and hit “Add”.

Implement index action
Open the TweetController class from the UserInterface project. Change the method body of the Index method so that it creates a new instance of the ReadModel.ReadModelDataContext. Use that instance to query all the TweetIndexItems from the context ordered by the TimeStamp. The code should look like this:
using System;
using System.Web.Mvc;
using ReadModel;
using UserInterface.Commanding;
using Commands;
using System.Linq;
namespace UserInterface.Controllers
{
public class TweetController : Controller
{
public ActionResult Index()
{
var context = new ReadModelDataContext();
var query = from item in context.TweetIndexItems
orderby item.TimeStamp descending
select item;
return View(query);
}
public ActionResult Add()
{
return View();
}
[HttpPost]
public ActionResult Add(PostNewTweetCommand command)
{
var service = new SimpleTwitterCommandServiceClient();
service.Execute(command);
return View();
}
}
}
Add ReadModel connectionstring to config
We should add a new connection string to the web.config that points to the local database file. Open the web.config in the root of the UserInterface project. Now add the following connection string section to it, but with a correct AttachDbFile attribute that contains the path the ReadModel.mdf in the ReadModel project folder:
<configuration>
<connectionStrings>
<add name="ReadModel.Properties.Settings.ReadModelConnectionString"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\pjvds\Documents\visual studio 2010\Projects\SimpleTwitter\ReadModel\ReadModel.mdf;Integrated Security=SSPI;User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<!-- rest of config –>
The last thing we should to is change the home page to the index view of the tweet controller and update the home item in the menu. Change the default action by double click in the global.asax file in the UserInterface project and change the controller in the MapRoute method call to “Tweet”. The code should look like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace UserInterface
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Tweet", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}
}
To change the Home item in the menu of the site go to the Site.Master file in the Views/Shared folder of the UserInterface. Change the first menu item in by changing the html of the ul-tag around line 24 to the following code:
<ul id="menu">
<li><%: Html.ActionLink("Home", "Index", "Tweet")%></li>
<li><%: Html.ActionLink("Post New", "Add", "Tweet")%></li>
<li><%: Html.ActionLink("About", "About", "Home")%></li>
</ul>
Give it a go!
Hit F5 and enjoy your first Ncqrs based system!
Good Work. I have concern regarding inheriting domain object from AggregateRootMappedByConvention.
Many thanks for writing this great introduction to implementing CQRS with the Ncqrs framework.
I had to implement DenormalizeEvent on TweetListItemDenormalizer but I think that was the only thing that wasn’t in your detailed instructions.
Nice tutorial, easy to folloy.
When will the master branch code be in sync with the one in the examples? I’m a bit confused between the differences (EventIdentifier versus AggregateRootId, etc.)
Thanks!
Some of the changes I had to make for this tutorial to work on a recent release of version 0.80 ncqrs-ncqrs-577ee22 from Aug 13, 2011
Events.TweetPostedEvent
inherit from SourcedEvent instead of DomainEvent
BootUp with the BootStrapper
Use:
var service = new Ncqrs.Commanding.ServiceModel.CommandService();
instead of:
var service = new InProcessCommandService();
Use:
return new MsSqlServerEventStore(“Data Source=.\\SQLEXPRESS;Integrated Security=SSPI;User Instance=True;AttachDbFilename=|DataDirectory|\\EventStore.mdf;”);
Instead of:
return new SimpleMicrosoftSqlServerEventStore(“Data Source=.\\SQLEXPRESS;Integrated Security=SSPI;User Instance=True;AttachDbFilename=|DataDirectory|\\EventStore.mdf;”);
Had to create EventStore database in SSMS using the TableCreationScript.sql located in c:\…\…\ncqrs-ncqrs-577ee22\Framework\src\Ncqrs\Eventing\Storage\SQL
Add reference to Newtonsoft.Json.dll to the CommandService and UserInterface projects
ReadModel
Inherit from Ncqrs.Eventing.ServiceModel.Bus.IEventHandler
instead of Ncqrs.Eventing.Denormalization.IDenormalizer
TweetListDenormalizer -> use:
var newItem = new TweetIndexItem();
instead of :
var newItem = new TweetListItem();
Microsoft Code Contracts are also required to build and run NCQRS. This is listed as a prereq in the NCQRS reference, but is missing on this page.
http://msdn.microsoft.com/en-us/devlabs/dd491992
@Cristobal — the Payload property of the event will give you access to the actual event object, which will contain the ID of the aggregate root(s?) you are affecting.
Came to a full stop when I couldn’t add the databases as they are a future version. I am still using sql server 2005 and have no desire to move higher just yet. With such a simple schema you would think an example should use the earliest version of sql possible. I’m busy guessing the schema from the one screenshot but I’m giving up now.
Great tutorial. I’m surprised that you have tightly-coupled the MVC controller to the Data Access layer (through the use of Linq2Sql), especially given how well separated the rest of the concerns are. This could be resolved quite simply with an extra couple of steps illustrating how to add a Repository for the ReadModel and the use of ViewModels within the controller and views.
Great, I still have questions about a few things but at least that makes a very nice introduction to the whole pattern. It is really useful to finally see something working and get the head out of the theory…