Domain events with Unity Container extension

I do like domain events perfectly described by Udi. I’d like to share my implementation of this pattern, using Unity (my preferable container), which seems to be simple, short and still powerful. I assume, that you read the Udi’s article carefully. First and foremost: the domain interfaces

    /// <summary>
    /// The markup interface for any system event.
    /// </summary>
    public interface IEvent
    {
    }

    /// <summary>
    /// The interface of a handler for events of type <typeparamref name="T"/>.
    /// </summary>
    /// <typeparam name="T">The type of the event to handle.</typeparam>
    public interface IEventHandler
        where T : IEvent
    {
        /// <summary>
        /// Handles the specified @event.
        /// </summary>
        /// <param name="event">The @event.</param>
        void Handle(T @event);
    }

    /// <summary>
    /// The interface of event manager, allowing raising events based on the <see cref="IEvent"/>.
    /// </summary>
    public interface IEventManager
    {
        /// <summary>
        /// Raises the specified event, not requiring, 
        /// that it is handled by any handler.
        /// </summary>
        /// <typeparam name="T">The type of the event.</typeparam>
        /// <param name="event">The @event.</param>
        /// <remarks>
        /// The method iterates through all of the registered handlers for the event of type <typeparamref name="T"/>.
        /// </remarks>
        void Raise(T @event)
            where T : IEvent;
    }

I assume usage of dependency injection and having the IEventManager implementation injected. Speaking about the IEventManager implementation it’s fairly simple, located in a project knowing the Unity assembly (Infrastructure in my case). It’s worth to mention, that I consider handlers to be transient objects, constructed and discarded immediately after event handling.

    /// <summary>
    /// The implementation of event manager using the container to resolve handlers.
    /// </summary>
    public class EventManager : IEventManager
    {
        private readonly IUnityContainer _container;

        [DebuggerStepThrough]
        public EventManager(IUnityContainer container)
        {
            _container = container;
        }

        [DebuggerStepThrough]
        public void Raise(T @event)
            where T : IEvent
        {
            var handlers = _container.&lt;ResolveAll&gt;();

            foreach (var handler in handlers)
            {
                try
                {
                    handler.Handle(@event);
                }
                finally
                {
                    _container.Teardown(handler);
                }
            }
        }
    }

The last but not least: how to register all the handlers in the container? I wrote a small unity extension providing assembly scan functionality which can be found below. The are two mouthful method names in the code:

  • GetFirstClosedGenericInterfaceBasedOnOpenGenericInterface, which tries to do what is written it does :P
  • RegisterInstanceWithSingletonLifetimeManager,an extension methods using a I-have-nothing-to-do-with-monitors LifetimeManager for setting up the singletons

The code itself:

    /// <summary>
    /// The <see cref="UnityContainer"/> extension registering all the event handlers
    /// and unity-based implementation of <see cref="IEventManager"/>.
    /// </summary>
    /// <remarks>
    /// The event handlers are regsitered as classes with transient lifetime. 
    /// Their instances are tear down immediately after usage.
    /// </remarks>
    public class EventUnityContainerExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            var eventManager = new EventManager(Container);
            Container.RegisterInstanceWithSingletonLifetimeManager(eventManager);
        }
        /// <summary>
        /// Registers all the event handlers from assembly of the passed type <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">The type which assembly should be scanned.</typeparam>
        /// <returns>This instance.</returns>
        public EventUnityContainerExtension RegisterHandlersFromAssemblyOf<T>()
        {
            return RegisterHandlersFromAssembly(typeof(T).Assembly);
        }

        /// <summary>
        /// Registers all the event handlers from all <paramref name="eventHandlersAssemblies"/>.
        /// </summary>
        /// <param name="eventHandlersAssemblies">List of assemblies to scan.</param>
        /// <returns>This instance.</returns>
        public EventUnityContainerExtension RegisterHandlersFromAssemblies(params Assembly[] eventHandlersAssemblies)
        {
            foreach (var eventHandlersAssembly in eventHandlersAssemblies)
            {
                RegisterHandlersFromAssembly(eventHandlersAssembly);
            }

            return this;
        }

        private EventUnityContainerExtension RegisterHandlersFromAssembly(Assembly assembly)
        {
            foreach (var type in assembly.GetTypes())
            {
                if (type.IsInterface || type.IsAbstract)
                {
                    continue;
                }

                var handlerInterface = type.GetFirstClosedGenericInterfaceBasedOnOpenGenericInterface(typeof(IEventHandler));
                if (handlerInterface == null)
                {
                    continue;
                }

                // the type is registered with a name, because only named registrations can be resolved by unity.ResolveAll method
                Container.RegisterType(handlerInterface, type, type.FullName, new TransientLifetimeManager());
            }

            return this;
        }
    }
}

Simple and powerful, isn’t it? :)

Hot links

This week brought a lot of good posts:

  • an interesting post from Ayende, which estimated costs of good/bad design. It’s worth mentioning that this post generated 10k visits on the original post, which Ayende commented. Maybe he should start a new kind-of-SEO company ;-)
  • an astonishing news from InfoQ about more http-bounded WCF. I’m looking forward to seeing it
  • finally, for cat lovers who I am not, The Oatmeal

NServiceBus callback failure

Today I found a bug in NServiceBus, which occured just before publishing our project. I isolated the bug, and published the unit test on the SourceForge, but I’m not quite sure whether the project is still alive (there are a few tickets untouched). The link to the isolated case: http://sourceforge.net/tracker/?func=detail&atid=1009068&aid=3092090&group_id=209277

The problem is a race condition which can occur when the service using Reply, replies before the callback is registered to the message. The scenario is simple: the reply message correlation id is not found in the dictionary and the message is consumed with no trace left. The callback registration occurs after this and hence, it will never be fired at all. Sad but true: this eliminates NServiceBus’ synchronous way to go.

It seems that for now, I cannot use callbacks at all (replying with messages handled by handlers works perfectly since it does not use this ‘correlation stuff’). Worth to notice, that I’ve got to redo a lot of work because of this ‘feature’.

Any thoughts about that?

I demand configuration

In the previous posts I described the intentions behind Themis. It’s time do deepen into demand and the whole configuration. Imagine a domain of car drivers. It includes car drivers as well as driven cars. The simplest demand which one can come up with is a simple check, whether one can drive a specific car.

public class CanDrive : IDemand<bool>
{
    public CanDrive(Car car)
    {
        Car = car;
    }

    public Car Car { get; private set; }
}

Speaking about a car and car driver:

public class DriverRole
{
    public DriverRole(int skillLevel)
    {
        SkillLevel = skillLevel;
    }

    public int SkillLevel { get; private set; }
}

public class Car
{
    public Car(int requiredSkillLevel)
    {
        RequiredSkillLevel = requiredSkillLevel;
    }

    public int RequiredSkillLevel { get; private set; }
}

The last but one thing, which should be done is to create a defintion of the DriverRole. By creating a definition I mean, creating a set of rules applied to evaluated demands in scope of the role context:

public class DriverRoleDefinition : RoleDefinition<DriverRole>
{
    public DriverRoleDefinition( )
    {
        Add<CanDrive, bool>((d, r) => d.Car.RequiredSkillLevel <= r.SkillLevel);
    }
}

Having all of this, during application startup one can easily configure the demand service with fluent configuration:

var demandService = Fluently.Configure()
    .AddRoleDefinition(new DriverRoleDefinition())
    .BuildDemandService();

and use the created service to evaluate demand canDrive created on a retrieved car basis, passing the driver role as the argument

return _demandService.Evaluate<CanDrive, bool>(canDrive,  driverRole).Any(b=>b);

In the solution, I created a more meaningful example (Themis.Example project), showing how with simple extension methods get rid of plenty of generic parameters.

In the next posts I’ll write about Themis extension points and describe a way in which I want to integrate it with NHibernate.

I demand IDemand

The main interface of Themis is IDemand.

public interface IDemand
{
}

An example implementations:

public class EntityPermission : IDemand
{
    public EntityPermission(TEntity entity)
    {
        Entity = entity;
    }

    public TEntity Entity { get; private set; }
}

public class View : EntityPermission
{
    public View(TEntity entity)
        : base(entity)
    {
    }
}

A simple interface, with no members at all. The class implementing it defines the demand name as well as the result which should be provided by the system evaluating the demand. Implementations of IDemand should be contextful, passing all the needed context for the demand evaluation in their properties. The TResult can be any type, but in majority of authorization cases it’ll be nothing more then bool. We want a yes/no answer for ‘Can I?’ question, don’t we? :)

Having the defined roles and demands we can move to the UI and write a simple authorization check. Being given an instance of IDemandService (by constructor injection), I can write in my ASP MVC controller a simple check of a demand/authorization. Below you can find the signature of IDemandService, a simple extension method written to ease using the service in a specific domain (a wrapping service is also a good solution) and the usage example itself.

public interface IDemandService
{
    IEnumerable<TResult> Evaluate<TDemand, TResult>(TDemand permission, params object[] roles)
        where TDemand : IDemand<TResult>;
}

Useful extension methods written in the app using Themis. The names, I hope, are self-descriptive.

    public static class AuthorizationServiceExtensionMethods
    {
        public static bool Can<TDemand>(this IDemandService demandService, TDemand permission, 
            params object[] roles)
            where TDemand : IDemand<bool>
        {
            return demandService
                .Evaluate<TDemand, bool>(permission, roles)
                .Any(b => b);
        }

        public static bool CanEdit<TEntity>(this IDemandService demandService, TEntity entity, 
            params object[] roles)
        {
            return demandService
                .Evaluate<Edit<TEntity>, bool>(new Edit<TEntity>(entity), roles)
                .Any(b => b);
        }

        public static bool CanView<TEntity>(this IDemandService demandService, TEntity entity, 
            params object[] roles)
        {
            return demandService
                .Evaluate<View<TEntity>, bool>(new View<TEntity>(entity), roles)
                .Any(b => b);
        }
    }

And finally, the app code example in which you can see that role management was delegated to an enigmatic IRoleService. The ‘Should I use NH session to manage roles?’ question is out of scope of this entry.

public ActionResult View(Guid id)
{
    var car = _session.Get<Car>(id);
    var roles = _roleService.GetCurrentUserRoles();
    if (!_demandService.CanView(car, roles))
        throw new InvalidOperationException("You cannot view this car!");

    return View(car);
}

Isn’t is simple? What about the expressions and the configuration? I’ll cover it soon.

It’s all about your domain

I dislike libraries which make me pollute the domain with any implementation and reference. I made up my mind about Log4Net and NHibernate, and now I’m totally cool to add the naked (not wrapped in a _super_abstracted_layered_total_wrap_ ) reference to my project and query the NH’s session treating it as the repository. What I dislike is when the friction between the library and application makes me leak its interfaces all around or wrap its plenty of interfaces.

The Themis is about providing an (in majority of cases) authorization system, with almost no overhead. In the last part I mentioned the three main parts of the Themis. I’ll start with the last, the most meaningful – your domain. Imagine a very complex system with plenty of roles. Imagine that each role can have a different context for different users, for instance:

  • Bob, has roles:
    • Administrator, with properties
      • SkillLevel: 5
      • Permissions: Permissions.Max
    • Worker, with properties
      • Floor: 4
    • Worker, with properties
      • Floor: 5
  • Alice, has roles:
    • Manager, with properties:
      • MobbingFloor: 4
    • Manager, with properties:
      • MobbingFloor: 7
      • Mobbing

As you can see roles, for me are not only simple strings, but rather containers for contexts and they should be included in your domain. Using NHibernate I’d create a base class Role and derive other roles from it. Additionally, I’d add a set property to the User, simply called Roles and that would be it. Going back to the contextful roles, it allows you to incorporate them into more meaningful statements like “Administrator can Manage only Programs with RequiredSkillLevel lesser then his/her”. A simple business rule having a few parts: the privilege itself – Manage, the subject of rule – Program, and the condition. Having the roles implemented in the way described earlier, I’d be very pleased if I could simply write a lambda expression having Role and Program as parameters and checking the relation between skill levels. I’ll write them in the next post.

To sum up: it’s all about your domain, having roles as nonempty entities with connected to the aggregate, the user.