Reputation: 1986
I'm working on an MVVM application. It has some objects that the whole application needs (single instances) and it has some objects that only certain windows/controls need (one instance per control).
I'd like to configure my StructureMap container to contain all the application instances, just like normal. When I open a window/control I'd like to create a clone of the container and add the objects needed by that control to the configuration of the clone. The clone should extend the original container and should contain the same configuration and instances.
Is this possible to do with StructureMap? (I'm looking at nested containers, but I'm not sure that's what I want).
More details...
Here's a test that shows the behavior. First the standard stuff:
[Test]
public void Mupp()
{
var parent = new Container(x =>
{
x.For<IMyServiceAgent>().Singleton().Use<MyServiceAgent>();
});
var parentServiceAgent = parent.GetInstance<IMyServiceAgent>();
Then I create the clone. It has the same instances as the parent. (It's is the implementation of the method CreateCloneOf()
that I'm looking for.)
IContainer scoped1 = CreateCloneOf(parent);
scoped1.GetInstance<IMyServiceAgent>().ShouldBeTheSameAs(parentServiceAgent);
I'd like to extend the configuration with my local objects.
scoped1.Configure(x =>
{
x.For<IMyPresenter>().Singleton().Use<MyPresenter>();
});
var scopedPresenter1 = scoped1.GetInstance<IMyPresenter>();
scoped1.GetInstance<IMyPresenter>().ShouldBeTheSameAs(scopedPresenter1);
Creating a second clone of the container will not share instances (or configuration) with the first clone.
IContainer scoped2 = CreateCloneOf(parent);
scoped2.Configure(x =>
{
x.For<IMyPresenter>().Singleton().Use<MyPresenter>();
});
scoped2.GetInstance<IMyPresenter>().ShouldNotBeTheSameAs(scopedPresenter1);
What's configured in the scoped conatiner should not be in the parent container
parent.GetInstance<IMyPresenter>(); // Should throw
It should be possible to create a scoped container from a scoped container.
IContainer moreScoped = CreateCloneOf(scoped1);
moreScoped.GetInstance<IMyPresenter>().ShouldBeTheSameAs(scopedPresenter1);
}
Upvotes: 1
Views: 457
Reputation: 9281
Judging by your question it sounds like what you're looking for is nested containers.
You can achieve your goal by creating a nested container (a nested container is a copy of the container suitable for short lived operations, any changes to the nested container are not reflected in the container it was cloned from - read more here).
Once you have you nested container you can then add a StructureMap registry for the new operations required for the module your nested container is to be used in.
Like so:
Setup:
public void ApplicationBootstrap()
{
IContainer container = StructureMapCoreSetup.Initialise();
container.Configure(c =>
{
c.IncludeRegistry<DefaultRegistry>();
});
}
Usage:
public class ApplicationModule
{
public ApplicationModule(IContainer container)
{
childContainer = container.GetNestedContainer();
childContainer.Configure(x =>
{
x.AddRegistry<ModuleSpecificRegistry>();
});
}
}
Any changes to the nested container will not be reflected in any container in any other containers (unless you created a nested instance of the nested container) and the container can be disposed of once you're finished with it.
Hopefully this is what you're looking for, or it's at least pointed you in the right direction!
Upvotes: 3