Castle windsor resolution pipeline with Unity as sub resolver
Shortly speaking I am trying to link Castle Windsor
container with Unity
container. Let me explain the context:
I have a project in which for very long time it used castle windsor. A few days ago, I got a bunch of dll's that I must consume / use from my old project. Those DLL's use Unity Container as their injection mechanism. I also have access to interfaces / implementations that are found in those dlls but I would not try to instantiate manually implementations but I would just prefer, if possible, to link the Unity container with my current castle windsor container. How could I achieve this?
So if I have:
public class MyService: IService
{
public MyService (IThidPartyService thirdParty)
{
}
}
If I resolve IService
with windsor it would be nice that IThirdPartyService
to be solved by the other container: Unity.
Thank you!.
I think this is a perfect example for the use of a custom ISubDependencyResolver
. Whenever Castle won't know how to resolve a specific dependency it will address that custom resolver. That new resolver will depend on the Unity Container and will use it to resolve "for" Castle.
Castle's documentation states that:
If previous places weren't able to resolve the dependency resolver will ask each of its sub resolvers (ISubDependencyResolver) if they can provide the dependency.
So when that dependency will not be found in Castle it will seek your new resolver which will provide the dependency.
Here is a working example with both Constructor Injection and Property Injection :
class Program
{
static void Main(string[] args)
{
var unityContainer = new UnityContainer();
unityContainer.RegisterType<IDependency, Dependency1>();
unityContainer.RegisterType<IPropertyDependency, PropertyDependency1>();
WindsorContainer castleContainer = new WindsorContainer();
castleContainer.Kernel.Resolver.AddSubResolver(new UnityResolver(unityContainer));
castleContainer.Register(
Component.For<SomeType>());
var result = castleContainer.Resolve<SomeType>();
}
}
public interface IDependency { void Foo(); }
public class Dependency1 : IDependency { public void Foo() { } }
public interface IPropertyDependency { }
public class PropertyDependency1 : IPropertyDependency { }
public class SomeType
{
public SomeType(IDependency dependency) { ConstructorDependency = dependency; }
public IDependency ConstructorDependency { get; private set; }
public IPropertyDependency PropertyDependency { get; set; }
}
public class UnityResolver : ISubDependencyResolver
{
public UnityResolver(UnityContainer container)
{
Container = container;
}
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return Container.Registrations.Any(z => z.RegisteredType.Equals(dependency.TargetType));
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)
{
return Container.Resolve(dependency.TargetType);
}
public UnityContainer Container { get; set; }
}
And the result:
As for the code for checking Unity
for the CanResolve
- I'm sure it can be improved - I do not know much about Unity