同一接口的Unity容器的多种实现 [英] Unity Container Multiple Implementations of same interface

查看:92
本文介绍了同一接口的Unity容器的多种实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究统一容器,并对如何将类的构造解析为接口的多个不同实现有一个快速的问题。

I'm studying up on the unity containers and have a quick question on how to resolve a class's construction to multiple different implementations of an interface.

这是我的代码:

public interface IRenderer
{
    void DrawSquare(Square square);
    void DrawCircle(Circle circle);
}

public interface IShape
{
    void Draw(IRenderer renderer);
}

public class Dx11Renderer : IRenderer
{
    public void DrawSquare(Square square)
    {
    }

    public void DrawCircle(Circle circle)
    {
    }
}

public class GlRenderer : IRenderer
{
    public void DrawSquare(Square square)
    {
    }

    public void DrawCircle(Circle circle)
    {
    }
}

public class Circle : IShape
{
    public void Draw(IRenderer renderer) { renderer.DrawCircle(this); }   
}

public class Square
{
    public void Draw(IRenderer renderer) { renderer.DrawSquare(this); }   
}

public class Canvas
{
    private readonly IRenderer _renderer;

    private List<Circle> _circles = new List<Circle>();
    private List<Square> _squares = new List<Square>(); 

    public Canvas(IRenderer renderer)
    {
        _renderer = renderer;
    }

    public void Draw()
    {
        foreach (Circle c in _circles)
        {
            c.Draw(_renderer);
        }

        foreach (Square s in _squares)
        {
            s.Draw(_renderer);
        }
    }
}

并进行注册/解决

        // Create the container
        var container = new UnityContainer();

        // registration

        container.RegisterType<IRenderer, GlRenderer>("GL");
        container.RegisterType<IRenderer, Dx11Renderer>("DX11");

        Canvas canvas = container.Resolve<Canvas>("GL");

这会引发 ResolutionFailedException,因此我必须使用不正确。

This throws a "ResolutionFailedException" so I must be using this incorrectly.

有人可以解释一下这是否是不好的做法,或者我该如何实现。

Can someone explain if this is bad practice, or how I can achieve this.

谢谢

更新:

所以我所做的是对Canvas进行了两次注册,每种依赖类型如下:

So what I have done is registered Canvas twice with each type of dependencies like so:

// Canvas with an OpenGL Renderer
container.RegisterType<Canvas>("GLCanvas", new InjectionConstructor(new ResolvedParameter<IRenderer>("GL")));
// Canvas with a DirectX Renderer
container.RegisterType<Canvas>("DXCanvas", new InjectionConstructor(new ResolvedParameter<IRenderer>("DX11")));

Canvas canvas = container.Resolve<Canvas>("GLCanvas");

对我来说这很好!

推荐答案

问题是您正在使用名称 GL解析Canvas,但尚未以这种方式注册Canvas。 Unity不会将名称传播为依赖关系解析,因此在解析IRenderer时不会使用名称 GL。

The problem is that you are resolving Canvas with the name "GL", but you have not registered Canvas in that way. Unity doesn't propagate the name to dependency resolution, so it won't use the name "GL" when resolving IRenderer.

有几种方法可以解决这个问题:使用Unity解决命名依赖项

There are several options to solve this already answered: Resolving named dependencies with Unity

您的问题是这是一个不好的做法,还是您如何获得相同的结果。以我的经验,尝试注册和解析同一接口的多个实例通常会导致代码混乱。一种替代方法是使用Factory模式创建Canvas实例。

Your question is whether this is a bad practice, or how you can achieve the same results. In my experience, trying to register and resolve multiple instances of the same interface usually leads to messy code. One alternative would be to use the Factory pattern to create instances of Canvas.

您是否需要使用容器来解析Canvas?如果没有理由,可以解决IRenderer并自己新建一个画布:

Do you need to use your container to resolve Canvas? If you don't have a reason not to, you could simply Resolve your IRenderer and new up a Canvas yourself:

new Canvas(container.Resolve<IRenderer>("GL"));

请记住,Unity只是一种工具,如果它似乎无法胜任您的工作需要,您可能需要另一种工具。

Remember that Unity is just a tool, if it doesn't seem to be capable of doing what you need, you may need a different kind of tool.

这篇关于同一接口的Unity容器的多种实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆