views:

294

answers:

2

With StructureMap one can do a resolution and force the container to use specific dependency instance provided at the time of resolution like so:

ObjectFactory.With<ISomeDependency>(someDepedencyInstance).GetInstance<IServiceType>()

Provided instance will be used in whole resolution chain, that is not only as a direct dependency of IServiceType implementation but also as a dependency of any direct and indirect dependencies of IServiceType implementation.

How do I do something like that in Castle Windsor?

I know I can provide a direct dependency with an overload of IWindsorContainer.Resolve<>(), but I need to provide this dependency to something deeper.

A: 

You can register an instance as the implementation of a given component like this:

container.Register(Component
    .For<ISomeDependency>()
    .Instance(someDependencyInstance));

This means that everytime you resolve anything and ISomeDependency is part of the resolved object graph, the someDependencyInstance instance will be used.

It that what you want, or did I misunderstand the question?


Based on additional information, here's a new attempt at answering the question.

You should be able to use container hierarchies for this. If a Windsor container can't resolve a type, it'll ask its parent. This means that you can create a child container that contains only the override and then ask that container to resolve the type for you.

Here's an example:

var container = new WindsorContainer();
container.Register(Component
    .For<ISomeDependency>()
    .ImplementedBy<SomeDependency>());
container.Register(Component
    .For<IService>()
    .ImplementedBy<Service>());

var childContainer = new WindsorContainer();
childContainer.Register(Component
    .For<ISomeDependency>()
    .ImplementedBy<SomeOtherDependency>());

childContainer.Parent = container;

var service = childContainer.Resolve<IService>();

The resolved service will contain an instance of SomeOtherDependency and not SomeDependency.

Notice how childContainer only overrides the registration of ISomeDependency. All other registrations are used from the parent.

Mark Seemann
I'm aware of this, but my need is different. Let's say I have ISomeDependency registered in the container, but for some specific, single resolution I want to force a specific instance (different than the registered one) that I provide at the time of resolution.
Artur
Okay, I think I understand you now. See my updated answer.
Mark Seemann
Yes, thank you Mark, that would be it. Although I must say that StructureMap makes this particular scenario way easier. Also, how do I get rid of the child container (make it available for GC)? Do I just let it go off the scope or should I set Parent to null, or maybe call container.RemoveChildContainer(childContainer)?
Artur
WindsorContainer implements IDisposable, so the correct thing would be to call its Dispose method, but first remove it from the parent by calling RemoveChildContainer.
Mark Seemann
+1  A: 

You could use a named component and service overrides:

var container = new WindsorContainer();
container.Register(Component.For<ISomeDependency>()
    .ImplementedBy<SomeDependency>());
container.Register(Component.For<ISomeDependency>()
    .ImplementedBy<SomeOtherDependency>()
    .Named("other"));
container.Register(Component.For<IService>()
    .ImplementedBy<Service>()
    .ServiceOverrides(ServiceOverride.ForKey("dep").Eq("other")));

See this article for more information on service overrides.

Mauricio Scheffer
I'm not sure that's what the OP is asking about. This will use "other" for all created instances of IService. I thought the question was whether you could override the behavior for a particular invocation of Resolve, but I might be wrong...
Mark Seemann
yes, it's not quite clear to me either...
Mauricio Scheffer
The point is to override the behaviour for a particular invocation of Resolve.
Artur
Normally overrides are done at registration time, not at resolution time.
Mauricio Scheffer