One or Multiple Containers

Feb 11, 2009 at 2:24 AM
I apologize if this has been discussed and I overlooked it:

I have orthogonal exports. Completely indepdendent in action and purpose (including one using a directory catalog and one an assembly catalog).

My gut feel is that these should use two different composition containers. But another part of me thinks this is a bad idea.

What's the prevailing wisdom?

Feb 11, 2009 at 8:12 AM
Edited Feb 11, 2009 at 8:14 AM
Can you give more information on your scenario, on first glance it doesn't feel lke they need to be two different containers. If you have multiple catalogs, you can create an AggregatingCatalog and pass both catalogs to it. Then feed that aggregating catalog to the container on it's constuction. Once you do that the container can query either.

The general wisdom on when to use containers is around scoping. From a scoping perspective, you could have a parent/child relationship where you have a root container, that contains a set of common exports that are then used by a set of child containers. For example you might be in a multi-tenant solution where each tenant provides their own set of services, yet they also share some common singletons. Below is an illustration of how these would be wired up.

var rootCatalog = ...
var rootContainer = new CompositionContainer(rootCatalog);

var customerACatalog = ...
var customerAContainer = new CompositionContainer(customerACatalog, rootContainer);

var customerBCatalog = ...
var customerBContainer = new CompositionContainer(customerBCatalog, rootContainer);

I've now established a hierarchy where rootContainer has two child containers. Let's say the rootContainer has an ILogger that has a shared lifetime. If any parts are created in the childContainers which import a logger, they will both share the same instance. I can also release / dispose of the customer containers, while the root shared container stays alive. This becomes important also in web scenarios, where I will have an app level container, along with page level / per request containers.

Another place where we see scoping used, when you want to build up an object graph completely in isolation of other graphs, but where there is no parent / child / shared relationship. For example you might create a container for a Job that is going to be processed, where you create the container for processing the job, and then release it when the job is processed. You use a separate container in order to configure it exactly with the specific dependencies the job will need. The job might take a device, where each job has a different type of device. Using a container, you can manually add the right device (such as a printer / plotter, or an inserter) to the container that the job needs so it gets injected with the right one.


Feb 11, 2009 at 12:45 PM

My two orthogonal issues would be template metadata providers (property providers for the template) and template processor.

However, in language/samples that have been used here, I think another exmple is a need for a provider of jobs resources (devices) and a logging provider. Because they entirely orthogonal, it seems to make sense for them to be scoped into different MEF containers.

I think what I understand from you is that yes you can, but you should have a clear understanding of why.

The hierarchical containers are very cool.