Quick-and-dirty unique constraints in Raven DB

Quick-and-dirty unique constraints in Raven DB

Raven DB, like most NoSQL databases designed to be fast and scale out, does not readily support enforcing uniqueness of fields between documents. If two users must not share the same email address or Facebook ID, you cannot simply add a unique constraint for it.

However, Raven DB does guarantee uniqueness in one place: each document must have a unique ID, or a ConcurrencyException will be thrown. By creating dummy documents with say, an email address for an ID, this feature can be effectively exploited to achieve unique constraints in Raven DB.

You can easily add this behaviour to your database if you install the Raven DB UniqueConstraints Bundle, which will enforce uniqueness on updates as well as inserts. However… if the field is immutable and you just want something quick and dirty you can use this: RavenUniqueInserter.cs 🙂

using (var session = documentStore.OpenSession()){    var user = new User                   {                       EmailAddress = "rdingwall@gmail.com",                       Name = "Richard Dingwall"                   };    try    {        new RavenUniqueInserter()            .StoreUnique(session, user, p => p.EmailAddress);    }    catch (ConcurrencyException)    {        // email address already in use    }}

It works by simply wrapping the call to DocumentSession.Store() with another document – in this case, it would also create a document with ID UniqueConstraints/MyApp.User/rdingwall@gmail.com, guaranteed to be unique.

You can grab it here: https://gist.github.com/1950991

DDD eXchange 2010 highlights

On Friday I attended DDD eXchange 2010, a one-day software conference here in London on Domain Driven Design. This years conference focused on two themes — architectural innovation and process — and I saw talks by Eric Evans, Udi Dahan, Greg Young, Ian Cooper and Gojko Azdic discussing their various aspects. Here are some of my highlights.

image

The difference between a Domain and a Domain Model

Eric Evan led the keynote focusing on definitions of many of the original terms that get mixed from the blue DDD book. In particular, he clarified the difference between the domain and the domain model:

  • Domain — the business. How people actually do things.
  • Domain Model — a useful abstraction of the business, modelled in code.

One is fixed (only the business can change it), the other is flexible. It sounds really obvious, but often the terms are used interchangibly and things get messy. Most notably:

  • DDD systems never have a domain layer — they have a domain model. Go and rename your Domain namespace to DomainModel right now.
  • Ubiquitous language is created to describe the domain model — it is not just blindly dictated from the existing domain. Mark Gibaud summarized this succinctly in a tweet:

Both of these are things I have been vocal about in the past.

The difference between a Sub-Domain and a Bounded Context

Following on from the previous point, another tricky one — a subdomain is a sub-part of the business (e.g. in a banking domain, a subdomain might be loans), where bounded contexts are more concerned with things like linguistic boundaries. They are easiest to spot when two business experts use the same words to refer to different concepts.

Likewise, a generic subdomain is not a reusable code library/service (like Google Maps) — it is an area of the business with no special differentiation. Compare this versus the core domain, where the business derives its competitive advantage through differentiating itself from the market.

CQRS

Much of the morning was spent discussing Command Query Responsibility Segregation (CQRS), Event Sourcing, persistent view models, and all that entails. If you’ve kept up with Greg and Udi’s recent talks, you didn’t miss anything.

image

In a paper-based system…

Greg mentioned a useful tool he sometimes uses when identifying roles and events in a business system: imagine how the business would operate if it were completely free of computers.

How did they stay afloat sixty years ago when people went home sick? Records got lost, or contained mistakes? Are there any old employees around you can talk to who still remember? The answers to these questions may provide insight into how the domain should be modelled.

This also led into an interesting discussion about how the rise of the multi-user RDBMS has led businesses to expect their software to be 100% consistent (even though their business processes never historically were, before they got computers), and how difficult it is nowdays to convince businesses to embrace scary prospects like eventually-consistency and the possibility of stale data.

Aggregates synchronize through events, not method calls

Ian Cooper mentioned this briefly in his session on implementing DDD on a large insurance company project. Basically, an aggregate must never call a method on another aggregate — doing so would violate each of their consistency boundaries. Instead, an interaction like this should be modelled as a domain event, with a separate handler coordinating its own consistency boundary (e.g. a transaction) for the second aggregate.

Final thoughts

Overall I had a fantastic time, and I highly recommend anyone to attend next year. Props to the Skills Matter staff and Eric for running such a great event!

Refactoring insight: base project for .NET domain-driven design applications

Refactoring insight: base project for .NET domain-driven design applications

In the past couple of weeks, I’ve started working on a new framework for my team, for developing domain-driven, test-driven web applications with ASP.NET MVC. Actually, it’s more of a meta-framework: a pattern for application development that leans on as many community-backed, best-of-class tools like NHibernate, NUnit, Rhino.Mocks, Json.NET etc as possible.

From time to time, however, I need to write my own utility class or interface, because it’s too specialised or not available elsewhere. To promote reuse and consistency between applications, I started putting them in a shared Foo.Core project (plus Foo.Core.Tests of course), similar to SharpArch.Core. Unfortunately, it began to turn into a bit of a mess; I had DDD-specific stuff like concept base classes and repository traits mixed in alongside generic LINQ extension methods and other random .NET utility classes.

It’s quite likely that some of the more generic stuff will be used in non-DDD projects, like SharePoint components and addins for Microsoft Office. But to a non-DDD developer, Foo.Core contains a lot of mysterious and scary stuff for whom the purpose of isn’t clear. This is not going to help adoption within my team.

To solve this problem, I decided to split the project in two. I now have a Foo.DomainDrivenDesign project that so far includes:

  • Repository Traits
  • Specification bases
  • DomainException
  • IEntityValidator<T>, RuleViolation and RuleViolationException
  • ObjectWithId<T>

The project name makes it immediately obviously what all this stuff is for. The rest has been dumped in Foo.Utilities:

  • DesignByContract
  • LINQ extensions

Hopefully in future, the Utilities project can be eliminated completely and replaced by Umbrella or Utilities.NET so we don’t have to maintain it.

St9exception with libstdc++

St9exception with libstdc++

Here’s something I encountered today when writing some C++:

try{    throw std::runtime_error("some message");}catch (std::exception e){    std::cout << "error: " << e.what() << std::endl;}

When run, this code will write “error: St9exception”, instead of “some message” to stdout. “St9exception” comes from libstdc++, in which the default value returned by std::exception::what() is the mangled symbol name. The mistake was that I was catching the exception by value, not by reference. (Too much C# perhaps?)

Instead it should have of course been:

try{    throw std::runtime_error("some message");}catch (const std::exception & e){    std::cout << "error: " << e.what() << std::endl;

Windows Integrated Authentication in ScrewTurn Wiki

Windows Integrated Authentication in ScrewTurn Wiki

ScrewTurn Wiki is a simple, open source wiki engine that reproduces much of the functionality found in Mediawiki. ScrewTurn Wiki is powered by ASP.NET 2 and Microsoft SQL Server, which makes it ideal for Windows-centric corporate environments. Unfortunately, ScrewTurn Wiki has no out-of-the box support for Windows Integrated Authentication (and, according to the developer, never will).

Windows Integrated Authentication allows users’ credentials to be automatically passed to IIS. This allows the application (if it supports it) to use Windows login details – i.e., the same user name across an entire domain. The user is automatically and seamlessly logged in to the application – a huge benefit over having to remember multiple user names and passwords.

I have created a simple Windows Integrated Authentication implementation for ScrewTurn Wiki, similar to that used by Community Server (another ASP.NET/SQL Server-based collaboration tool). Note that ScrewTurn Wiki’s Plugin Framework does not cater for extra functionality at this level (yet). When a new session is spawned on the web server, the application searches for an account matching the user’s login name. If none is found, a new account is created automatically. Events are logged via the standard ScrewTurn Wiki event log.

Replace Session_Start in ScrewTurn Wiki’s Global.asax with the following:

void Session_Start(object sender, EventArgs e){    // Code that runs when a new session is started    ScrewTurn.Wiki.Users.OnlineUsers++;    ScrewTurn.Wiki.SessionFacade.Breadcrumbs = new ScrewTurn.Wiki.BreadcrumbsManager();    // Get identity name from web server.    string identityName = System.Web.HttpContext.Current.User.Identity.Name;    if (identityName == null || identityName.Length < 1)        throw new System.ApplicationException("Could not get current Windows user name." +            "Ensure Integrated Windows Authentication is enabled.");    string username;    // Strip domain prefix (e.g. "\COMPANY.NETDoeJ").    int domainDelimOffset = identityName.IndexOf("\");    if (domainDelimOffset > 0)        username = identityName.Substring(domainDelimOffset + 1);    else        username = identityName;    if (username.Length < 1)        throw new System.ApplicationException("Username " + identityName +            " is empty after domain stripped.");    // Locate user.    ScrewTurn.Wiki.PluginFramework.UserInfo user =            ScrewTurn.Wiki.Users.Instance.Find(username);    if (user == null)    {        // User not found, add a new one.        if (!ScrewTurn.Wiki.Users.Instance.AddUser(username, string.Empty,                string.Empty, true, false, null))            throw new System.ApplicationException("Could not add user ""                + username + "".");            // Get freshly-added user.            user = ScrewTurn.Wiki.Users.Instance.Find(username);            if (user == null)                throw new System.ApplicationException("Could not find user ""                    + username + "".");    }    // Set up session.    ScrewTurn.Wiki.SessionFacade.LoginKey =        ScrewTurn.Wiki.Tools.ComputeSecuredUsernameHash(user.Username);    ScrewTurn.Wiki.SessionFacade.Username = user.Username;    ScrewTurn.Wiki.SessionFacade.Admin = user.Admin;    // Log event.    ScrewTurn.Wiki.Log.LogEntry("User " +        ScrewTurn.Wiki.SessionFacade.Username +        " logged in through Windows Integrated Authentication",        ScrewTurn.Wiki.EntryType.General, "SYSTEM");}

For more information about Windows Integrated Authentication and ScrewTurn Wiki (including comments on this implementation), see this thread at the ScrewTurn Wiki forum.