Rich domain objects with DivineInject

DivineInject is a .net dependency injection framework, designed to be simple to use and easy to understand.

You can find the source for DivineInject on github. In this second part in the series we’ll look at creating rich domain objects, the first part covers getting started with Divine Inject.

Simple Domain Objects

As an example, imagine I have a simple shopping basket in my application. The shopping basket is encapsulated by a Basket object, for which the interface looks like this:

interface IBasket
{
    IList<IBasketItem> GetBasketContents();
    void AddItemToBasket(IBasketItem item);
}

The contents of the basket are actually backed by a service to provide persistence:

interface IBasketService
{
    IList<IBasketItem> GetBasketContents(Guid basketId);
    void AddItemToBasket(Guid basketId, IBasketItem item);
}

I can create a very simple implementation of my Basket:

class Basket : IBasket
{
    private readonly IBasketService _basketService;
    private readonly Guid _basketId = Guid.NewGuid();

    public Basket(IBasketService basketService)
    {
        _basketService = basketService;
    }

    public IList<IBasketItem> GetBasketContents()
    {
        return _basketService.GetBasketContents(_basketId);
    }

    public void AddItemToBasket(IBasketItem item)
    {
        _basketService.AddItemToBasket(_basketId, item);
    }
}

Since I’m using dependency injection, IBasketService sounds like a dependency, so how do I go about creating an instance of Basket? I don’t want to create it myself, I need the DI framework to create it for me, passing in dependencies.

I want to do something with how the Basket is created, so let’s start with a simple interface for creating baskets:

interface IBasketFactory
{
    IBasket Create();
}

When I’m creating a basket I don’t care about IBasketService or other dependencies; calling code just wants to be able to create a new, empty basket on demand. How would we implement this interface? Well, I could do the following – although I shouldn’t.

class BadBasketFactory : IBasketFactory
{
    public IBasket Create()
    {
        // DON'T DO THIS - just an example
        return new Basket(
            DivineInjector.Current.Get<IBasketService>());
    }
}

Now I’d never suggest actually doing this, explicitly calling the dependency injector. The last thing I want from my DI framework is to have references to it smeared all over the application. However, what this class does is basically what I want to happen.

DivineInject however can generate a class like this for you; this is configured at the same time you define the rest of your bindings:

DivineInjector.Current
    .Bind<IBasketFactory>().AsGeneratedFactoryFor<Basket>();

This generates an IBasketFactory implementation, which can create new IBasket implementations on demand (they will all actually be instances of Basket); all without having references to the DI framework smeared across my code. If I want to use the IBasketFactory, for example from my Session class, I declare it as a constructor arg the same as I would any other dependency:

public Session(IAuthenticationService authService, 
               IBasketFactory basketFactory)
{
    _authService = authService;
    _basketFactory = basketFactory;
}

The DI framework takes care of sorting out dependencies and I get a Session class with no references to DivineInject. When I need a new basket I just call _basketFactory.Create(). Since I have nice interfaces everywhere, everything is easy to mock so I can TDD everything.

Rich Domain Objects

Now what happens as my domain object becomes more complex? Say, for example, I want to be able to pass in some extra arguments to my constructor. Returning to our basket example: as well as starting a new, empty basket – isn’t there a possibility that I want to continue using an existing basket? E.g. in case of load balanced servers or fail-over. What do I do then?

I start by changing Basket, to allow me to pass in an existing basket id:

private readonly IBasketService _basketService;
private readonly Guid _basketId;

public Basket(IBasketService basketService)
{
    _basketService = basketService;
    _basketId = Guid.NewGuid();
}

public Basket(IBasketService basketService, Guid basketId)
{
    _basketService = basketService;
    _basketId = basketId;
}

I now have two constructors, one of which accepts a basket id. Since all Basket instances are created by an IBasketFactory, I need to change the factory interface, too:

interface IBasketFactory
{
    IBasket Create();
    IBasket UseExisting(Guid id);
}

I now have a new method on my IBasketFactory, if I was hand-coding the factory class I’d expect this second method to call the second constructor, passing in the basket id.

What do we need to tell DivineInject to make it generate this more complex IBasketFactory implementation? Nothing! That’s right, absolutely nothing – DivineInject will already generate a suitable IBasketFactory. Our original declaration above, is still sufficient:

DivineInjector.Current
    .Bind<IBasketFactory>().AsGeneratedFactoryFor<Basket>();

This generates an IBasketFactory implementation, returning a Basket instance for each method it finds on the interface. Since one of these methods takes a Guid, it tries to find a matching constructor which also takes a Guid, plus any dependencies it knows about. DivineInject can automatically wire up the right factory method to the right constructor, using the arguments it finds in each. Now, when a session wants to re-use an existing basket it just calls:

_basketFactory.UseExisting(existingBasketId)

This creates a new Basket instance, with dependencies wired up, passing in the basket id. Everything is still using interfaces so all your collaborations can be unit tested. Behind the scenes DivineInject generates the IL code to implement your factory interfaces, leaving you free to worry about your design.

By following this pattern we can create rich domain objects that include both state and dependencies: it becomes possible to create stateful objects that have behaviours (methods) that make sense in the domain. Successfully modelling your domain is critical to creating code that’s easy to understand and easy to change. DivineInject helps you model your domain better.

Advertisements

Getting started with DivineInject

DivineInject is a .net dependency injection framework, designed to be simple to use and easy to understand.

You can find the source for DivineInject on github.

Why another DI framework?

Because dependency injection is important – but done wrong it can do more harm than good. DivineInject is opinionated about the right way to use dependency injection:

  • Constructor injection or death
    Setter injection is bad for your health, so just say no
  • Dependencies are singletons
    Dependencies are external to your application – your DI framework doesn’t need to know about users or sessions or threads.
  • Domain objects can be rich, too
    Your domain model doesn’t have to be anemic

Constructor Injection

Setter and method injection are much harder to get right – so DivineInject simply doesn’t support them. If you can’t implement your dependencies as constructor arguments, then maybe you should refactor the dependency so you can.

Singleton Dependencies

Dependencies are external to your application. They are external things that your application depends on like databases and web services; these things are generally used across your application. Hint: if a dependency is only used in one or two places, it isn’t an application-wide dependency.

Things like users and sessions are domain concepts in your domain, not in the domain of dependency injectors. All dependency injection frameworks get wrapped up in different scopes, which makes the frameworks harder to use. DivineInject simply doesn’t support them — if you need something user-scoped or session-scoped, then implement the logic yourself. It isn’t hard, and if you ever want to understand the lifecycle of your objects it’s in your code, not mine — which will make reasoning about your code or debugging it a million times easier.

Rich Domain Objects

DivineInject borrows an idea from Google Guice – with Guice it is called “assisted injection”, in DivineInject we call it generated factory injection. The idea is the same — providing a simple way to create objects with constructors which accept runtime arguments as well as dependencies to inject. This allows you to create rich, stateful domain objects which also have dependencies.

Getting Started

So how do you get started with DivineInject? I’ll assume you’ve not been living under a rock and already know what dependency injection is. In which case basic usage of DivineInject boils down to three steps:

  • Add the dependency
  • Configure bindings
  • Create your root object

Add the Dependency

DivineInject is available as a NuGet package:

Install-Package DivineInject

Configure Bindings

When DivineInject creates a new instance of a class it calls a constructor, each of the constructor arguments is a dependency of the class — something external to the class, for which an implementation must be provided. But how do we know which value to pass for each dependency? This is controlled by the bindings.

Your bindings must be configured near the start of your application — e.g. in the main method or global.asax.

There are basically two ways to configure bindings with DivineInject.

1) bind an interface to a concrete type. DivineInject will pass the same (singleton) instance of the given concrete type whenever it encounters a constructor argument of the interface type.

DivineInjector.Current
	.Bind<IOrdersService>().To<OrdersService>();

2) bind an interface to a specific instance. DivineInject will pass the given instance whenever it encounters a constructor argument of the interface type.

var myOrdersService = new OrdersService(...);
DivineInjector.Current
	.Bind<IOrdersService>().ToInstance(myOrdersService);

Create Your Root Object

DivineInject allows you to create a tree of objects — each object has references to dependencies, which in turn reference their own dependencies; forming a tree of objects. This tree is created starting with the root object — e.g. in a WPF application the root would be the outermost ViewModel; in a WCF application it would be the service class.

The root object is created by calling DivineInject — any arguments the root object constructor requires are taken from the bindings. This should be the only time you explicitly call DivineInject to create objects.

There are two ways of creating the root object:

1) by explicit type:

private MainWindowViewModel CreateViewModel()
{
    return DivineInjector.Current.Get<MainWindowViewModel>();
}

2) by passing the type as an argument:

public object GetInstance(InstanceContext instanceContext, 
                          Message message)
{
    return DivineInjector.Current.Get(_instanceType);
}

At this point you now have a very simple set of dependencies configured, which can be wired up by DivineInject. E.g.

public class MainWindowViewModel
{
    public MainWindowViewModel(IOrdersService ordersService)
    {
        ...
    }
}

I can define classes which accept an instance of an interface as a constructor argument, when DivineInject instantiates this class it will pass in the right implementation of the interface, the one configured by the bindings.

In the second part of this series, we’ll look at how we use DivineInject to create classes that aren’t singletons.