我正在研究统一容器,并有一个关于如何将类的构造解析为接口(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/