Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,640
|
Comments: 51,260
Privacy Policy · Terms
filter by tags archive
time to read 3 min | 470 words

Glenn and Chris has already gotten the word out, but that is an important piece of news.

The idea is based off a post that Jeremy Miller had about a month ago, having a common, shared interface across several IoC implementation. That would allow library authors to make use of the benefits of a container without taking a dependency on a particular implementation.

The alternative for that is to each library to create its own abstraction layer. A good example of that is NServiceBus' IBuilder interface, or ASP.NET MVC's IControllerFactory. That is just annoying, especially if you are integrating more than a single such framework.

This project was created with the aid of most of the IoC containers authors on the .NET framework, and we have adapters for Windsor, Unity, Spring.NET already, with adapters for the rest of the containers coming soon.

What it is not?

It is not meant to be a complete container abstraction. The reason that the interface is so small (and you wouldn't believe the amount of time that it took to settle on exactly what is going to be there) is that this is not supposed to be the container that you are using. This is explicitly designed to be a read only interface that allows a library to use the container, not some uber container interface (which doesn't really make sense considering the differences between the containers).

Why Service Locator vs. Container? Again, the design is focused on enabling integration scenarios, more than anything else.

I still recommend to avoid explicit service locator usage whenever possible, and to rely on the container and dependency injection. This is not always possible, which is what this library is supposed to solve.

Who should use this?

If you are releasing a piece of code that is taking a dependency on a container, you should consider that as an option. It is generally considered to be a better idea than to force your choice of containers on the clients. The OAuth library for .NET is going to move to this, for exactly this reason.

I am from Microsoft, can I use this?

The code is released under the MS-PL, and all of the work on the project was done by Microsoft employees. That was quite intentional, since this is allow Microsoft projects to make use of that (this is Microsoft IP). If you are a Microsoft employee, you can make use of that. In fact, according to Chris, the next version of the Enterprise Library is going to use this as the container abstraction, so you'll be able to use the Enterprise Library with Windsor and StructureMap and Spring.NET and Ninject and AutoFac and all the rest of the things that I forgot.

I can use only Microsoft products, can I use this?

See previous question.

Where can I find the code

The codeplex site is here: http://www.codeplex.com/CommonServiceLocator

time to read 4 min | 699 words

The Managed Extensibility Framework is "new library in .NET that enables greater reuse of applications and components. Using MEF, .NET applications can make the shift from being statically compiled to dynamically composed. If you are building extensible applications, extensible frameworks and application extensions, then MEF is for you."

(I was too lazy to think about my own description for it, so I just copied the official one.)

Probably the first thing that you should know about MEF is what will undoubtedly be the most common cause for confusion.

The Managed Extensibility Framework is not an IoC container.

image This is not a slug at MEF, it is an important distinction. If you try to judge MEF through IoC container glasses, you will come away confused. It may walk like a duck, but it meows.

MEF is, first and foremost, a composition framework. And its target audience are BIG applications. Those two, taken together, are important to understand what MEF is and how we should look at it.

What is the difference between a composition framework and an IoC container? On the surface, they are doing much of the same thing, managing dependencies for the application in an automated fashion. The difference (and the devil) are in the details.

IoC containers have long ago stopped just managing dependencies. They are taking care of a lot of additional responsibilities. Managing lifecycles, proxies, aspect orientation, event aggregation, transaction semantics and a lot of other features.

In addition to that, there is a lot of focus on problem solving by utilizing the container. Things like generic specialization or component selectors allows you to approach a lot of very complex problems in a completely different mindset.

A composition framework, on the other hand, is focused on a single goal: dependency management.

It sounds like MEF is a subset of what an IoC container is doing, I know. This is not the case. MEF, the bits we have right now, are doing a lot more in the area of dependency management than the containers are doing. Where a container is usually static and opaque, MEF primary focus is to make the dependency management itself a dynamic and transparent process.

This is where the second part of the MEF design goals come into place. MEF is targeting Big applications. The really big ones. One of the immediate customers of MEF is Visual Studio itself.

Things like ( take a deep breath ):

  • being able to query meta data without loading assemblies
  • statically verify the dependency graph for all the components and reject those that would put the system in in valid state
  • being explicit by default
  • contract adapters
  • discovery
  • metadata tagging

All of those are key concepts in the overall dependency management theme. And all of those are the product of having a Visual Studio being one of the first consumers of this project. Visual Studio needs this kind of things, across tens of thousands of components. And MEF is setup to handle those kind of scenarios.

So, MEF is very similar to IoC containers, but it has very different goals (or maybe it would be more accurate to say that it has very different priorities).

Another important aspect of MEF has nothing to do with it at all and everything to do with where it is going to be used. MEF is going to ship with .Net 4.0, which put it in a position to be very widely distributed, but more importantly, since it is on the framework, it can be used by other parts of the framework. Which is where it get interesting.

There are a lot of places in the framework that could make use of a container. IControllerFactory is a good example of something that should not exists, for example. I am ambivalent with regards to that, because I think that the correct abstraction for those kind of things is not necessarily MEF, but that is beside the point.

And that is enough for now, I am going to toss a coin and see if it is going to be Erlang code or meta documentation next.

time to read 6 min | 1003 words

Jacob have an interesting perspective on testability:

The thing is that using Typemock means that you can unit test literally any public method of any public class, regardless of any and all internal dependencies that class might have. And you can do so without changing the design and/or architecture of your software at all.

In other words, using Typemock means that everything is testable. Unit testable. Seriously. Everything.
....
Which is why I had such a hard time reading Jeffrey Palermo's latest blog post entitled “Inversion of Control is NOT about testability”. Since I know Jeffrey Palermo is a .Net developer, my initial response is a big fat “Duh. He must be using Typemock.” Sadly, this is not the case.
...

“Testable design” only has value in the things it allows us to do—namely, unit test our classes. If we can unit test our classes as easily no matter what design patterns we choose, then that frees us up to explore other aspects of design choices. It isn't that <le design du jour> ceases to have value, it's just that testability is no longer a factor in evaluating its utility.
...

So, uh, forget all I just said. Spend lots of time making sure your .Net projects are testable. Also: Typemock sucks. Don't bother going there...

There are so many things that I disagree with in this post, I am not sure where to even begin. Before that, I need to point out, as usual, that TypeMock is an awesome tool, and that it can bring a lot of value to the table. It doesn't fit the way that I , personally, works, but that is a personal opinion, and I am just a little bit biased. I just want to make it clear that this post is not an attempt to dismiss TypeMock or its value.

With that out of the way, let us concentrate on the actual content of the post.

First, there is no silver bullet. TypeMock is wonderful, but it is not the answer to every testability prayer (is there such a thing?). If the code is bad, TypeMock can do a lot to help, but it will still be a PITA to test this code.

Second, it looks like Jacob missing the actual message in Palermo's post about "this is not about testability". Good design is one which preserves separation of concerns, maintain the single responsibility principal, amenable to change, etc. This also happen to be a design that is easily testable, but that is beside the point.

Good design is simple one where each piece of the code does one thing, and is not dependent on everything else in the application. To violate that means that you would run into issues the first time you need to make a modification. The reason that we want to avoid dependencies as much as possible is that we have to avoid the cascading change reaction.

I didn't have to look far for an example, two posts prior to this one, Jacob has given an excellent example why a design that is testable with TypeMock (and thus, holy*), run into problems with real world requirements. This is not my scenario, it is his. I can come up with quite a lot of war stories about the problems that code with too much dependencies caused.

Let us take Rhino Mocks as an example (I still think of it as my best work), the project is over 3 years old, started in .Net 1.1 and C# 1.0. It has got through numerous versions and grown through two (and a half :-)) major framework versions. The code is stable and as usable as the the day I started this project. If you dig into Rhino Mocks, you'll find that the code is heavily segregated. That allowed me to add functionality and modify the way things work without difficulty, even when dealing with major changes, like the move to Dynamic Proxy 2 or support the AAA syntax.

That is what you get out of having a good design, software that is maintainable.

* sorry, this is a snipe at Jacob, not TypeMock.

time to read 12 min | 2398 words

One of the most common issues when people are building frameworks and applications that rely on a container is that they are not giving the container enough to do. Basically, they use the container to create some components, but they are doing a lot of things that the container could do for them outside of the container.

Note: Code for this post can be in the Scratch Pad.

NServiceBus and Mass Transit are good examples of that. I detailed some of the issues that I had with Mass Transit a while ago. Udi and I talked about this situation with NServiceBus a few days ago, and this is my attempt to figure out a better model for configuring NSB. Let us start from what we have right now.

We have XML configuration in app.config:

<MsmqTransportConfig InputQueue="messagebus" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5"
/>

<UnicastBusConfig DistributorControlAddress="" DistributorDataAddress="">
  <MessageEndpointMappings>
      <add Messages="Messages" Endpoint="messagebus" />
  </MessageEndpointMappings>
</UnicastBusConfig>

<MsmqSubscriptionStorageConfig Queue="subscriptions" />

And we have code to initialize the bus:

new ConfigMsmqSubscriptionStorage(builder);
NServiceBus.Serializers.Configure.BinarySerializer.With(builder);
new ConfigMsmqTransport(builder)
	.IsTransactional(true)
	.PurgeOnStartup(false);
new ConfigUnicastBus(builder)
	.ImpersonateSender(false)
	.SetMessageHandlersFromAssembliesInOrder(
		typeof(RequestDataMessageHandler).Assembly
		);
IBus bus = builder.Build<IBus>();
bus.Start();

The ConfigXyz objects are there to configure the bus itself inside the builder (the container used in the sample.

My first step was to take this and move it to Windsor, and with no XML config. Which gave me this:

// configure bus
container.Register(
	Component.For<IBuilder>()
		.ImplementedBy<WindsorBuilderAdapter>(),
	Component.For<IMessageSerializer>()
		.ImplementedBy<BinaryMessageSerializer>(),
	Component.For<ITransport>()
		.ImplementedBy<MsmqTransport>()
		.DependsOn(new
		{
			InputQueue = "messagebus",
			NumberOfWorkerThreads = 1,
			ErrorQueue = "error",
			MaxRetries = 5,
			PurgeOnStartup = true,
			IsTransactional = false
		}),
	Component.For<ISubscriptionStorage>()
		.ImplementedBy<MsmqSubscriptionStorage>()
		.DependsOn(
		new
		{
			Queue = "subscriptions"
		}
		),
	Component.For<IBus>()
		.ImplementedBy<UnicastBus>()
		.DependsOn(new
		{
			ImpersonateSender = false,
			MessageOwners = new Hashtable
			{
				{"Messages", "messagebus"}
			},
			MessageHandlerAssemblies = new[]
			{
				typeof (RequestDataMessageHandler).Assembly
			}
		})
	);

// configure handlers
container.Register(
	// yuck, we are registering concrete type!
	Component.For<RequestDataMessageHandler>()
	);


var bus = container.Resolve<IBus>();
bus.Start();

There are a few things that you would notice here. We have a lot more code, we hard code the configuration all over the place, you either need to understand Windsor or you have to copy/paste this, no XML (yeah!).

Some of this is good (no XML), the rest... need some work. If we will consider the fact that this is more or less standard bus configuration (configure bus on top of MSMQ), we will see that there is quite a lot we can do here to encapsulate the entire mess into a mechanism that would be much easier to work with.

In Windsor, packaging functionality is done using facilities. A facility is an extension to the container that contains certain behavior. It can be as simple as packaging up registration for several components into a single facility or it can be as complex as proxies and runtime component selections.

Let us start with what the least common denominator. A Windsor facility with XML configuration. The configuration I came up with is:

<configuration>
	<facilities>
		<facility
		   id="NServiceBusFacility"
		   type="Windsor.Infrastructure.NServiceBusFacility, Windsor.Infrastructure"
		   useBinarySerialization="true"
		   subsciptionQueue="subscriptions">
			<transport inputQueue="messagebus" errorQueue ="error"/>
			<bus impersonateSender="false">
				<message name="Messages" destination="messagebus"/>
				<handler name="Server"/>
			</bus>
		</facility>
	</facilities>

	<components>
		<component id="RequestDataMessageHandler" 
			type="Server.RequestDataMessageHandler, Server"/>
	</components>

</configuration>

And the code to make this happen is here (minus utility methods that I am not showing):

public class NServiceBusFacility : AbstractFacility
{
	public bool UseXmlSerialization { get; set; }
	public bool UseBinarySerialization { get; set; }

	protected override void Init()
	{
		UseXmlSerialization = FacilityConfig.Value("UseXmlSerialization");
		UseBinarySerialization = FacilityConfig.Value("UseBinarySerialization");

		Kernel.Register(
			Component.For<IBuilder>()
				.ImplementedBy<WindsorBuilderAdapter>()
			);


		RegisterTransport();
		RegisterSerializer();
		RegisterSubscription();
		RegisterBus();
	}

	private void RegisterBus()
	{
		var bus = FacilityConfig.Children["bus"];
		if (bus == null)
			throw new InvalidOperationException("bus is a mandatory element");
		var messageOwners = new Hashtable();
		var assemblies = new List<Assembly>();
		foreach (var element in bus.Children)
		{
			if (element.Name == "message")
			{
				AddMessageDestination(element, messageOwners);
			}
			else if (element.Name == "handler")
			{
				AddHandlerAssebmly(element, assemblies);
			}
			else
			{
				throw new InvalidOperationException("Unknown element in bus: " + element.Name);
			}
		}
		Kernel.Register(
			Component.For<IBus>()
				.ImplementedBy<UnicastBus>()
				.DependsOn(new
				{
					MessageOwners = messageOwners,
					MessageHandlerAssemblies = assemblies
				})
			);
	}

	private static void AddHandlerAssebmly(IConfiguration handler, ICollection<Assembly> assemblies)
	{
		string assemblyString = handler.Attributes["name"];
		if (string.IsNullOrEmpty(assemblyString))
			throw new InvalidOperationException("name attribute is mandatory in handler element");
		assemblies.Add(Assembly.Load(assemblyString));
	}

	private static void AddMessageDestination(IConfiguration message, IDictionary messageOwners)
	{
		string messsageName = message.Attributes["name"];
		if (string.IsNullOrEmpty(messsageName))
			throw new InvalidOperationException("message must have a name");
		string destination = message.Attributes["destination"];
		if (string.IsNullOrEmpty(destination))
			throw new InvalidOperationException("message must have a destination");

		messageOwners[messsageName] = destination;
	}

	private void RegisterSubscription()
	{
		string attribute = FacilityConfig.Attributes["subsciptionQueue"];
		if (attribute == null)
			throw new InvalidOperationException("subsciptionQueue is a mandatory attribute");
		Kernel.Register(
			Component.For<ISubscriptionStorage>()
				.ImplementedBy<MsmqSubscriptionStorage>()
				.Parameters(
				Parameter.ForKey("Queue").Eq(attribute)
				)
			);
	}

	private void RegisterTransport()
	{
		IConfiguration transport = FacilityConfig.Children["transport"];
		if (transport == null)
			throw new InvalidOperationException("transport is mandatory element");
		Kernel.Register(
			Component.For<ITransport>()
				.ImplementedBy<MsmqTransport>()
				.Parameters(

				// mandatory
				transport.Parameter("InputQueue"),
				transport.Parameter("ErrorQueue"),

				// optional
				transport.Parameter("numberOfWorkerThreads", "1"),
				transport.Parameter("MaxRetries", "5"),
				transport.Parameter("PurgeOnStartup", "false"),
				transport.Parameter("IsTransactional", "false")

				)
			);
	}

	private void RegisterSerializer()
	{
		AssertValidSerializationSettings();

		if (UseBinarySerialization)
		{
			Kernel.Register(
				Component.For<IMessageSerializer>()
					.ImplementedBy<BinaryMessageSerializer>()
				);
		}

		if (UseXmlSerialization)
		{
			Kernel.Register(
				Component.For<IMessageSerializer>()
					.ImplementedBy<XmlMessageSerializer>()
				);
		}
	}

	private void AssertValidSerializationSettings()
	{
		if ((UseXmlSerialization && UseBinarySerialization) || (!UseXmlSerialization && !UseBinarySerialization))
		{
			throw new InvalidOperationException("Must define either XML or Binary, not both.");
		}
	}
}

I am not happy with this yet, the facility has a lot of code there, and we still have XML, but we have very little configuration and the code to use this is now:

IWindsorContainer container = new WindsorContainer("windsor.config");

var bus = container.Resolve<IBus>();
bus.Start();

Which is much better than both versions. It also doesn't require me to recompile to modify the configuration.

Hold the press, what about administrator configuration?!

One of the major emphasis that NServiceBus has in its configuration API it the explicit distinction it makes between developer level configuration (dependencies, which transport you are using, transactions, who handles what, etc) and administrator level configuration (queue names, mostly).

In the configuration above we have no such separation. Problem, isn't it?

Again, we can use the container itself as a way to deal with this. First, we will define a configuration file, which will contain the following text:

<configuration>
	<properties>
		<subscriptionsQueue>subscriptions</subscriptionsQueue>
		<inputQueue>messagebus</inputQueue>
		<errorQueue>error</errorQueue>
	</properties>
</configuration>

And now in the configuration file itself we will include this configuration file, and refer to those values:

<configuration>
	<include uri="file://Configuration.config"/>
	<facilities>
		<facility
		    id="NServiceBusFacility"
		    type="Windsor.Infrastructure.NServiceBusFacility, Windsor.Infrastructure"
		    useBinarySerialization="true"
		    subsciptionQueue="#{subscriptionsQueue}">
			<transport inputQueue="#{inputQueue}" errorQueue ="#{errorQueue}"/>
			<bus impersonateSender="false">
				<message name="Messages" destination="messagebus"/>
				<handler name="Server"/>
			</bus>
		</facility>
	</facilities>

	<components>
		<component id="RequestDataMessageHandler" 
			 type="Server.RequestDataMessageHandler, Server"/>
	</components>

</configuration>

And just like that, we got ourselves a nice dual configuration, one for the administrators and one for the developers.

I am still not happy with this, because I have XML and a lot of code to deal with this XML nonsense, but we did drop down to a very simple XML configuration with very little time.

Let us see what is going to happen if we will use Binsor...

Since we don't want to have replication of the XML syntax (we can do much better without the limitations of XML), we will start from scratch, and define a new facility.

Note: While writing this several improvements to Binsor itself occurred to me, so this is certainly something that can be improved.

The approach for building configuration language using Binsor is fairly simple. Create an object graph that represent your configuration, and just call it from the Binsor script.

We start by defining the configuration model:

public enum SerializationFormat
{
	Xml,
	Binary
}

public class Transport
{
	public Transport()
	{
		//default values for optional params
		NumberOfWorkerThreads = 1;
		MaxRetries = 5;
		PurgeOnStartup = false;
		IsTransactional = false;
	}
	public string InputQueue { get; set; }
	public string ErrorQueue { get; set; }
	public int NumberOfWorkerThreads { get; set; }
	public int MaxRetries { get; set; }
	public bool PurgeOnStartup { get; set; }
	public bool IsTransactional { get; set; }
}

public class Bus
{
	public IDictionary MessageOwners { get; set; }
	public Assembly[] MessageHandlerAssemblies { get; set; }
}

public class UnicastBus : Bus { }

As you can see, this is about as simple as it can get.

Then we define the facility itself:

public class NServiceBusFacility_Binsor : AbstractFacility
{
	public SerializationFormat SerializationFormat { get; set; }
	public string SubsciptionQueue { get; set; }
	public Transport Transport { get; set; }
	public Bus Bus { get; set; }

	public NServiceBusFacility_Binsor(
		SerializationFormat serializationFormat,
		string subsciptionQueue,
		Transport transport,
		Bus bus)
	{
		SerializationFormat = serializationFormat;
		SubsciptionQueue = subsciptionQueue;
		Transport = transport;
		Bus = bus;
	}

	protected override void Init()
	{
		Kernel.Register(
			Component.For<IBuilder>()
				.ImplementedBy<WindsorBuilderAdapter>()
			);

		Kernel.Register(
			Component.For<ITransport>()
				.ImplementedBy<MsmqTransport>()
				.DependsOn(Transport)
			);

		switch (SerializationFormat)
		{
			case SerializationFormat.Binary:
				Kernel.Register(
				Component.For<IMessageSerializer>()
					.ImplementedBy<BinaryMessageSerializer>()
				);
				break;
			case SerializationFormat.Xml:
				Kernel.Register(
				Component.For<IMessageSerializer>()
					.ImplementedBy<XmlMessageSerializer>()
				);
				break;
			default:
				throw new NotSupportedException("Serialization format " + SerializationFormat + 
" is not supported"); } Kernel.Register( Component.For<ISubscriptionStorage>() .ImplementedBy<MsmqSubscriptionStorage>() .Parameters( Parameter.ForKey("Queue").Eq(SubsciptionQueue) ) ); Kernel.Register( Component.For<IBus>() .ImplementedBy<NServiceBus.Unicast.UnicastBus>() .DependsOn(Bus) ); } }

It is significantly simpler than the XML configuration based one. And now we can get to the configuration itself:

import System.Reflection
import Windsor.Infrastructure
import Server

facility NServiceBusFacility_Binsor:
	serializationFormat = SerializationFormat.Binary
	transport = Transport ( 
		InputQueue: "messagebus",
		ErrorQueue: "errors"
	)
	subsciptionQueue = "subscriptions"
	bus = UnicastBus (
			MessageOwners : {
				"Messages" : "messagebus"
			},
			MessageHandlerAssemblies : ( Assembly.Load("Server"), )
	)
	
component RequestDataMessageHandler

Wait! What about administrator configuration? Now that we are using a script to configure our application, it is even more important to separate the administrative configuration from the application configuration.

We will take the exact same approach as we did before. Creating a separate file for administration purposes. In order to do so in a way that gives the admin a nice syntax for configuration, we will define a configuration model:

public class MyConfiguration
{
	public static string InputQueue { get; set; }
	public static string ErrorQueue { get; set; }
	public static string SubscriptionsQueue { get; set; }
}

Now we can create the default AdminConfiguration.boo file:

import Windsor.Infrastructure # namespace of MyConfiguration

MyConfiguration.SubscriptionsQueue = "subscriptions"
MyConfiguration.InputQueue = "messagebus"
MyConfiguration.ErrorQueue  = "error"

And our Windsor.boo file is now:

import System.Reflection
import Windsor.Infrastructure
import Server
import file from AdminConfiguration.boo

AdminConfiguration().Run() # execute admin configuration

facility NServiceBusFacility_Binsor:
	serializationFormat = SerializationFormat.Binary
	transport = Transport ( 
		InputQueue: MyConfiguration.InputQueue,
		ErrorQueue: MyConfiguration.ErrorQueue
	)
	subsciptionQueue = MyConfiguration.SubscriptionsQueue
	bus = UnicastBus (
			MessageOwners : {
				"Messages" : "messagebus"
			},
			MessageHandlerAssemblies : ( Assembly.Load("Server"), )
	)
	
component RequestDataMessageHandler

Now we don't have any XML involved, but the format that we have is suspiciously similar to the way we worked when we had XML. So, except from a small reduction in the configuration complexity, what did we gain?

We have a full fledged programming language for our configuration purposes. We can now apply rules to our configuration, make logic based decisions, etc.

As a simple example, instead of having to hard code the message owners and handlers, we can scan the application directory for matching assemblies. Want to add a new handler, drop it into the directory, done. This is a really powerful concept, and I am using this extensively in my applications.

Note: Code for this post can be in the Scratch Pad.

time to read 1 min | 94 words

This is the entire Binsor config file for a real application:

import Castle.MonoRail.Framework
import Castle.MonoRail.WindsorExtension
import Rhino.Commons.Facilities from Rhino.Commons.ActiveRecord

facility MonoRailFacility
facility RhinoTransactionFacility
facility ActiveRecordUnitOfWorkFacility:
	assembly = "HibernatingRhinos"

for type in AllTypesBased of IController("HibernatingRhinos"):
	component type.Name, type
	
for type in AllTypes("HibernatingRhinos").WhereNamespaceEq("HibernatingRhinos.Services"):
	component type.GetServiceInterface(), type

And I am pretty confident that I am not going to have to do much in the future with those.

And yes, you can do it with the fluent registration API as well.

time to read 1 min | 102 words

Here is the syntax that I am getting at...

for type in AllTypesBased of IView("Rhino.Commons.Test"):
	component type
	
for type in AllTypesWithAttribute of ControllerAttribute("Rhino.Commons.Test"):
	component type
	
for type in AllTypes("Rhino.Commons.Test") \
	.WhereNamespaceEq("Rhino.Commons.Test.Binsor"):
	component type

for type in AllTypes("Rhino.Commons.NHibernate") \
	.Where({ t as System.Type | t.Name.Contains("NHRepository") }):
	component "nh.repos", type.GetSeriveInterface(), type

And this seems to cover just about any scenario that I can think of. Combine that with Binsor's extend facility, and we are more or less done.

time to read 4 min | 643 words

Udi Dahan has been talking about this for a while now. As usual, he makes sense, but I am working in different enough context that it takes time to assimilate it.

At any rate, we have been talking about this for a few days, and I finally sat down and decided that I really need to look at it with code. The result of that experiment is that I like this approach, but am still not 100% sold.

The first idea is that we need to decouple the service layer from our domain implementation. But why? The domain layer is under the service layer, after all. Surely the service layer should be able to reference the domain. The reasoning here is that the domain model play several different roles in most applications. It is the preferred way to access our persistent information (but they should not be aware of persistence), it is the central place for business logic, it is the representation of our notions about the domain, and much more that I am probably leaving aside.

The problem here is there is a dissonance between the requirements we have here. Let us take a simple example of an Order entity.

image As you can see, Order has several things that I can do. It can accept an new line, and it can calculate the total cost of the order.

But those are two distinct responsibilities that are based on the same entity. What is more, they have completely different persistence related requirements.

I talked about this issue here, over a year ago.

So, we need to split the responsibilities, so we can take care of each of them independently. But it doesn't make sense to split the Order entity, so instead we will introduce purpose driven interfaces. Now, when we want to talk about the domain, we can view certain aspect of the Order entity in isolation.

This leads us to the following design:

image

And now we can refer to the separate responsibilities independently. Doing this based on the type open up to the non invasive API approaches that I talked about before. You can read Udi's posts about it to learn more about the concepts. Right now I am more interested in discussing the implementation.

First, the unit of abstraction that we work in is the IRepository<T>, as always.

The major change with introducing the idea of a ConcreteType to the repository. Now it will try to use the ConcreteType instead of the give typeof(T) that it was created with. This affects all queries done with the repository (of course, if you don't specify ConcreteType, nothing changes).

The repository got a single new method:

T Create();

This allows you to create new instances of the entity without knowing its concrete type. And that is basically it.

Well, not really :-)

I introduced two other concepts as well.

public interface IFetchingStrategy<T>
{
	ICriteria Apply(ICriteria criteria);
}

IFetchingStrategy can interfere in the way queries are constructed. As a simple example, you could build a strategy that force eager load of the OrderLines collection when the IOrderCostCalculator is being queried.

There is not complex configuration involved in setting up IFetchingStrategy. All you need to do is register your strategies in the container, and let the repository do the rest.

However, doesn't this mean that we now need to explicitly register repositories for all our entities (and for all their interfaces)?

Well, yes, but no. Technically we need to do that. But we have help, EntitiesToRepositories.Register, so we can just put the following line somewhere in the application startup and we are done.

EntitiesToRepositories.Register(
	IoC.Container, 
	UnitOfWork.CurrentSession.SessionFactory, 
	typeof (NHRepository<>),
	typeof (IOrderCostCalculator).Assembly);

And this is it, you can start working with this new paradigm with no extra steps.

As a side benefit, this really pave the way to complex multi tenant applications.

time to read 1 min | 110 words

Dependency Injection & Inversion of Control Containers are not about testing!

I hear this a lot recently. Dave Laribee mentioned that in the Hanselminutes podcast, The creators of Guise seems to think that this is the main concern (01:30 in the video).

Oh, those techniques help, obviously. But it is not about unit testing.

For me, it is like saying that the main purpose interfaces is to enable easier testing.

DI & IoC are about decoupling, better flexibility, having a central place to go to and increasing the maintainability of out applications. Testing is important, but that is not the first and foremost reason.

time to read 2 min | 399 words

A few days ago I presented my typical way of handling container driven polymorphism.

// only use for selection
public interface IRegion<T> : IRegion {}

public void SetRegion(DependencyObject containerElement, string regionName)
{
	IRegion region = (IRegion) IoC.TryResolve(typeof(IRegion<>).MakeGenericType(containerElement.GetType()));

	if (region != null)
		_regions.Add(regionName, region);
}

I got an email with some good questions, and it is worth a second post to clarify. The questions:

The only thing I don’t like is that a lookup in the form of TryResolve(typeof(IRegion<>).MakeGenericType(containerElement.GetType())) would infer an explicit wrapper type for ever possible UI container type. On one hand it gives me the fine grain control I need to specify a different wrapper for an inherited UI container. But on the other hand, it means that ListBox, TreeView, ComboBox and TabControl would all need their own custom wrappers even though they all derive from ItemsControl and all handle adding and removing child entities in the same way.

But if containerElement == typeof(ListBox), won’t TryResolve(typeof(IRegion<>).MakeGenericType(containerElement.GetType())) fail to resolve? TryResolve expects an explicit match. It would need to find a registration for IRegion<ListBox>, not IRegion<ItemContainer> right? (Assuming Unity here.)

Even if that worked, what if I want all elements that inherit from ItemContainer to be handled by IRegion<ItemContainer> except TreeView? Say I need to handle TreeView differently for some reason. What’s a nice way to handle the 80% rule generically but still allow an override for special cases?

My response to that is very simple. Take the same approach, but bigger. Here is all we need to make this happen.

public void SetRegion(DependencyObject containerElement, string regionName)
{
	Type current = containerElement.GetType()
	while(current != typeof(DependencyObject))
	{
		IRegion region = (IRegion) IoC.TryResolve(typeof(IRegion<>).MakeGenericType(current));
	
		if (region != null)
		{
			_regions.Add(regionName, region);
			return;
		}
		
		current = current.BaseType;
	}
}

Now, we can register the following:

  • IRegion<TreeView>
  • IRegion<MyCustomRegion>
  • IRegion<ItemsControl>

And no matter what we will send to SetRegion, we can modify the behavior merely by changing the registration of IRegion<T> implementations. Note that this doesn't assumes any capacity on the container (except the basic resolve-generic-service one).

This is also a very natural model to follow, in nearly all cases (there is an issue here regarding whatever we should consider interfaces as well, but that is beside the point for this demo, and I would generally not do that anyway).

time to read 2 min | 376 words

I talked about ways to avoid invasive API design, and a lot of people asked about how to handle this with a container. First, I want to make it clear that the previous example assumed that you can't rely on a container, so it used Poor Man IoC to do that. Now that we can assume that there is a container, this is another matter entirely.

The API design now shifts to allow me to select the proper implementation from the container automatically. This generally ends up being either as a naming convention on top of a fixed interface, or as a generic interface with a given type as a parameter. The decision depends on what you are doing, basically, and the capabilities of your tools.

For myself, I strongly favor the generic interface approach, which would give us the following syntax:

public interface IMessageHandler<TMsg>
	where TMsg : IMessage
{
	void Handle(TMsg msg);
}

public class EndPoint
{
	public void HandleMsg(IMessage msg)
	{
		// this should be cached and turned into a delegate
		// not reflection call
		GetGenericHandleMsgMethod().MakeGenericMethod(msg.GetType())
			.Invoke(this, new object[]{msg});
	}

	public void HandleMsg<TMsg>(TMsg msg)
		where TMsg : IMessage
	{
		IoC.Resolve<IMessageHandler<TMsg>().Handle(msg);
	}

}

There is some ugliness in invoking the method with the generic parameter, but this allows you to handle a wide variety of cases very easily.

Let us take another example, this time it is from the Prism.Services.RegionManagerService:

public void SetRegion(DependencyObject containerElement, string regionName)
{
	IRegion region = null;

	if (containerElement is Panel)
	{
		region = new PanelRegion((Panel)containerElement);
	}
	else if (containerElement is ItemsControl)
	{
		region = new ItemsControlRegion((ItemsControl)containerElement);
	}

	if (region != null)
		_regions.Add(regionName, region);
}

I don't really like this code, let us see what happens when we introduce the idea of the container as a deeply rooted concept:

// only use for selection
public interface IRegion<T> : IRegion {}

public void SetRegion(DependencyObject containerElement, string regionName)
{
	IRegion region = (IRegion) IoC.TryResolve(typeof(IRegion<>).MakeGenericType(containerElement.GetType()));

	if (region != null)
		_regions.Add(regionName, region);
}

Now the code is much clearer, we can extend it from the outside, without modifying anything when we add a new region type.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. API Design (10):
    29 Jan 2026 - Don't try to guess
  2. Recording (20):
    05 Dec 2025 - Build AI that understands your business
  3. Webinar (8):
    16 Sep 2025 - Building AI Agents in RavenDB
  4. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  5. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
View all series

Syndication

Main feed ... ...
Comments feed   ... ...