我正在研究统一容器,并且有一个关于如何将类的构造解析为接口的多个不同实现的快速问题.
这是我的代码:
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
您的问题是这是一种不好的做法,还是如何实现相同的结果.根据我的经验,尝试注册和解析同一界面的多个实例通常会导致代码混乱.另一种方法是使用Factory模式创建Canvas实例.
您是否需要使用容器来解析Canvas?如果你没有理由不这样做,你可以简单地解决你的IRenderer并自己新建一个画布:
new Canvas(container.Resolve<IRenderer>("GL"));
请记住,Unity只是一种工具,如果它似乎无法满足您的需求,您可能需要一种不同的工具.