Can Windsor cooperate with another IoC container?
Asked Answered
I

1

6

In the core of our application, we use Castle Windsor to manage our dependencies. We'll be loading plugins from third parties which may be using their own IoC containers. We'd like them to be able to receive dependencies from the core, e.g. through constructor injection of the core's services, but also receive dependencies from their own IoC container.

It seems like if they supplied a service provider interface, Windsor could use it to resolve unknown dependencies, ignoring the results (since the lifetime of these components is someone else's business) and keep on trucking.

But I am also sure there are some great subtleties that come up when you attempt something like this.

Integumentary answered 13/5, 2011 at 6:3 Comment(3)
That's a very bad idea. Mixing containers is like mixing alcohols - it never ends well.Asthenopia
It certainly seems hangover-inducing, but surely we're not the first application which wants to use one container, but make friends with libraries which chose another.Integumentary
It sounds like we're trying to solve the same problem here. Read this post: https://mcmap.net/q/1778692/-common-service-registry. Did you manage to find a solution?Iolanthe
L
6

That's not necessary. If you enable those plugins to use Constructor Injection to get the appropriate services from your host application, Castle Windsor can wire up the PlugIn correctly. PlugIns simply use Constructor Injection as a way to statically declare a dependency, so as long as Windsor can resolve the dependency, the PlugIn will receive it.

What happens inside of each PlugIn (including use of other containers) is of no concern of the host application.

Lorylose answered 13/5, 2011 at 7:35 Comment(11)
But those programmers may wish to use IoC to register their own internal dependencies that the core IoC has never heard of.Integumentary
MEF addresses this type of problem through attributes. If that sort of add-in scenario is core to your application, it would be a better fit.Lorylose
Indeed the problem is that even if we are all conscientious and use constructor injection to get our dependencies, we have a situation where no one container has knowledge of all those dependencies, so can't create the object. I couldn't write a constructor for MyThing(ICoreService s, IMyPluginService p), since the core container could satify s and not p, and vice versa for the plugin's container.Integumentary
That wouldn't necessarily be the case with MEF since it doesn't use configuration, but rather discovery. As long as there's an [Export] which can satisfy an [Import] they will be matched.Lorylose
Sure, but then we're using MEF everywhere -- back to one container to rule them all. The question was about using multiple containers. Am I being dense?Integumentary
I think it would be a very rare occasion where a PlugIn would require a previously unknown dependency that it couldn't satisfy itself. However, if that were to be the case, you could always provide the Windsor configuration for that particular component in XML configuration. That would be possible without needing to recompile the core application.Lorylose
You could also use some of the new (very MEF-like) directory scanning features of Castle Windsor combined with a few convention and (again) Constructor Injection in the plugins to support that scenario.Lorylose
In any case, no matter how you look at it, the core application effectively controls the plugin contract. It probably already requires plugins to implement a specific interface or derive from a base class. What's so problematic about expanding that contract to also say "if you need any services you don't own yourself, you can request them through Constructor Injection"? That doesn't prevent them from using a different container internally if that's what they want, but it keeps that usage as a pure implementation detail that doesn't leak out of the plugin.Lorylose
The Core may magically-autodiscover implementers of ICoreInterface. A plugin writer has built HisInterestingImplementation, with constructor arguments IAnotherCoreService and ISomeServiceOnlyFoundInThisPlugin. The core IoC container could inject an instance of IAnotherCoreService, but would be at a loss at how to satisfy ISomeServiceOnlyFoundInThisPlugin. Either we expose registration facilities to the plugin, or ask the plugin to expose resolution facilities to us.Integumentary
Watch out for that - it sounds like it would lead to the Service Locator anti-pattern. That's why MEF uses a discovery mechanism instead of explicit configuration.Lorylose
Agreed, it doesn't seem to me like there's a very elegant answer, but I was a little surprised to see so little discussion on the topic.Integumentary

© 2022 - 2024 — McMap. All rights reserved.