Jonathan Birkholz

Structure Map Basics 2.6

I’ve had doing Structure Map posts on my To-Do list for a long time now. It is time to spring clean these items and get some posts up!

Like my other learning posts / projects, you can find the code at : http://github.com/RookieOne/Learning

I don’t want to dive into how / why you can use a DI / IOC tool like StructureMap. Or why SM over another IoC tool. So I won’t. :)

My recommendation is prefer to use a tool made by people who think about the problem the same way you do. You will be happier and self-discover features more easily.

I like the way Jeremy Miller thinks and naturally love Structure Map.

Normal Registration

Previously to register an interface with a concrete type there was a fluent by extremely verbose interface. With 2.6 that has been greatly simplified for a For().Use() syntax.

1
2
3
4
5
6
7
8
9
10
[Test]
public void IFoo_should_resolve_to_Foo()
{
var container = new Container();
container.Configure(x => x.For<IFoo>().Use<Foo>());
var foo = container.GetInstance<IFoo>();
foo.ShouldBeType<Foo>();
}

Singleton Registration

To register the type as a singleton, we just need to add a Singleton() call between our For and Use calls.

1
2
3
4
5
6
7
8
9
10
11
[Test]
public void should_return_same_instance_of_Foo()
{
var container = new Container();
container.Configure(x => x.For<IFoo>().Singleton().Use<Foo>());
var foo1 = container.GetInstance<IFoo>();
var foo2 = container.GetInstance<IFoo>();
foo1.ShouldBeTheSameInstanceAs(foo2);
}

Open Generic Registration

One of the cool things with StructureMap is the ability to register open generics. I know other tools support this, but it is still cool. So in this test I am registering an open generic interface IRepository<> with a concrete yet still open generic implementation Repository<>. I can then asked for a IRepository and I get back a Repository.

1
2
3
4
5
6
7
8
9
10
[Test]
public void IRepositoryT_should_resolve_to_RepositoryT()
{
var container = new Container();
container.Configure(x => x.For(typeof (IRepository<>)).Use(typeof (Repository<>)));
var repository = container.GetInstance<IRepository<Book>>();
repository.ShouldBeType<Repository<Book>>();
}

Open Generic with Closed Generic Alternative

Now this is where things get real cool. Besides registering an open generic concrete implementation, I can also registered a closed generic alternative. So in my test I am registering Repository<> for all IRepository<>. But I am also registering CustomerRepository with IRepository.

So with this I can have a general implementation but then provide specific implementations for those exceptional cases.

1
2
3
4
5
6
_container = new Container();
_container.Configure(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
x.For<IRepository<Customer>>().Use<CustomerRepository>();
});

Now for the tests pay close attention to the request to the container. Notice how the user of the container doesn’t need to know if the implementation they are using is the generic or the specific alternative. Isn’t that sweet!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Test]
public void IRepository_book_should_resolve_to_Repository_book()
{
var repository = _container.GetInstance<IRepository<Book>>();
repository.ShouldBeType<Repository<Book>>();
}
[Test]
public void IRepository_customer_should_resolve_to_Customer_Repository()
{
var repository = _container.GetInstance<IRepository<Customer>>();
repository.ShouldBeType<CustomerRepository>();
}

Naturally there are tons of other things Structure Map does but this was just a brief intro to some of the basics. I plan on blogging a bit more on some of the other neat features that make SM my IoC tool of choice.