How do I configure a single component instance providing multiple services in Castle.Windsor?
Asked Answered
K

4

6

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?

Khalil answered 26/3, 2009 at 1:57 Comment(0)
L
3

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!

Leatherette answered 26/3, 2009 at 3:14 Comment(0)
B
1

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.

Bill answered 15/7, 2009 at 7:24 Comment(1)
Is there a way to do this from the configuration XML?Khalil
I
0

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.

Ileneileo answered 26/3, 2009 at 14:36 Comment(2)
The main problem with this is using the "new" operator, which means you don't use autowiring for AB.Bill
Last line should be something like container.Register( Component.For<IB>().Instance( ab).Named("IBImplementation") ); or you'll get ComponentRegistrationException: Component AB could not be registered. There is already a component with that name.Ferbam
S
0

I was searching for the same answer, and this post is the farthest I could get with google. I found that using

Classes.FromThisAssembly().Where(t => t.FullName == "Namespace.Classname").WithServiceAllInterfaces()

Seems to do the trick for me.

Saltine answered 5/6, 2014 at 15:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.