Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Castle windsor resolution pipeline with Unity as sub resolver

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!.

like image 510
George Lica Avatar asked Oct 05 '16 11:10

George Lica


People also ask

Is Castle Windsor part of the GUI framework?

Note: For simplicity's sake, this example is a basic console application rather than GUI-based. The same principles would apply in a GUI application using DI/IoC. Castle Windsor is a third-party IoC container, meaning that it is not part of the .NET framework itself.

Is Castle Windsor a di/IoC container?

The same principles would apply in a GUI application using DI/IoC. Castle Windsor is a third-party IoC container, meaning that it is not part of the .NET framework itself. We will be using the NuGet Package Manager to install and reference the Castle components:

What is @Castle Windsor in Visual Studio 2019?

Castle Windsor is a third-party IoC container, meaning that it is not part of the .NET framework itself. We will be using the NuGet Package Manager to install and reference the Castle components: By default, the package manager console will open at the bottom of the Visual Studio window:

What is the best development environment for Castle Windsor?

If you're just starting out, I recommend Visual Studio Community Edition, a free development environment for applications targeting the .NET framework. It's important to note that while this tutorial uses Castle Windsor as an IoC container, there are several other frameworks that offer similar functionality:


1 Answers

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

like image 194
Gilad Green Avatar answered Oct 17 '22 06:10

Gilad Green