我正在研究统一容器,并有一个关于如何将类的构造解析为接口(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”,因此我必须错误地使用它。

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

谢谢

更新:

所以我所做的是用每种类型的依赖项注册 Canvas 两次,如下所示:
// 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”。

有几个选项可以解决这个已经回答的问题:Resolving named dependencies with Unity

您的问题是这是否是一种不好的做法,或者您如何才能获得相同的结果。根据我的经验,尝试注册和解析同一接口(interface)的多个实例通常会导致代码困惑。一种替代方法是使用工厂模式来创建 Canvas 的实例。

你需要用你的容器来解析Canvas吗?如果你没有理由不这样做,你可以简单地解析你的 IRenderer 并自己新建一个 Canvas :

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

请记住,Unity 只是一个工具,如果它似乎不能满足您的需求,您可能需要另一种工具。

关于c# - Unity Container 同一接口(interface)的多种实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23669502/

10-16 09:05