views:

145

answers:

3

I'd like to configure the Windsor container so that a single, singleton-style instance can provide two or more services through the container.

I've found that using the same type in multiple component declarations (XML-based config) will result in an instance of that type being created to provide each component's service interface, which is not the behaviour I desire.

For example:

interface IA { }
interface IB { }
class AB : IA, IB { ... }

I want the one instance of AB to provide both the IA and IB services.

The specific reason I want to do this is that my concrete DAO implementation extends multiple interfaces. On the flip side, I have several worker components which hold a reference to different interfaces. The concrete DAO instance respects this, but the constructors of these seperate worker components want the implementation of their seperate interfaces and I desire Castle.Windsor to pass the same object instance through to these worker containers via the respective service requests.

lol, I think that was clear as mud! :P

Does anyone understand what I mean, and has anyone got any ideas how I can acheive this through the XML configuration fo the components?

+1  A: 

Have you checked out the answer to this question (especially the forum post link) that appears to be what you are looking for. Some of the examples are using the Transient lifecycle but I think it will work with Singleton also.

The main pay-off of the forum post is:

container.Register(Component.For<IEntityIndexController, ISnippetController>()
.ImplementedBy<SnippetController>()
.LifeStyle.Transient);

The solution is uses the fluent interface (and a recent trunk build) and it wasn't possible to configure in xml last I saw. However, it may be possible with a facility.

Good luck!

Steven Lyons
+1  A: 

You can register an instance of an object (instead of an implementation) to be responsible for different implementations:

  var ab = new AB();
  container.Register( Component.For<IA>().Instance( ab) );
  container.Register( Component.For<IB>().Instance( ab) );

I believe that should work. However, that requires in code configuration, for apparent reasons.

jishi
The main problem with this is using the "new" operator, which means you don't use autowiring for AB.
Igor Brejc
A: 

Have you tried using the Forward method:

container.Register(Component.For<IEntityIndexController>()
.ImplementedBy<SnippetController>()
.Forward (typeof(ISnippetController))
.LifeStyle.Transient);

From my experiments and from the documentation:

register the service types on behalf of this component

i think it shoud do the trick.

Igor Brejc
Is there a way to do this from the configuration XML?
Ash
I don't know :(
Igor Brejc