Castle windsor resolution pipeline with Unity as sub resolver
Asked Answered
E

1

7

Shortly speaking I am trying to link Castle Windsor container with Unitycontainer. 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!.

Epimorphosis answered 5/10, 2016 at 11:38 Comment(0)
S
6

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:

enter image description here

As for the code for checking Unity for the CanResolve - I'm sure it can be improved - I do not know much about Unity

Shouldst answered 5/10, 2016 at 11:44 Comment(4)
I've tried this. The ideea is that ... HOW would castle know that he has to inject a specific interface through property injection? The only way he could know is by having that interface in the dependency map. Otherwise he would not even try to inject it.Epimorphosis
@GeorgeLica - As for property injection it doesn't seem to me to be a problem - See documentationShouldst
@Alexandru Marculescu - Please consider awarding the bounty :) The answer solves this questionShouldst
@GeorgeLica - Did the solution above help you solve the problem?Shouldst

© 2022 - 2024 — McMap. All rights reserved.