Unity Container Multiple Implementations of same interface

前端 未结 2 1081
鱼传尺愫
鱼传尺愫 2020-12-31 12:14

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.

H

2条回答
  •  失恋的感觉
    2020-12-31 12:41

    There is a way to inject the right renderer in the canvas on startup time. If you know the render method on startup you can register only the right renderer like this:

    var container = new UnityContainer();
    container.RegisterType();
    if (CheckIfItIsDx11)
    {
        container.RegisterType();
    }
    else
    {
        container.RegisterType();
    }
    

    when you want to resolve the canvas just use:

    var canvas = container.Resolve();
    

    if you dont know the renderer on startup time there is a way to. Like this:

    container.RegisterType("DX11");
    container.RegisterType("GL");
    
    
    var renderer = container.Resolve("DX11");
    var canvas = container.Resolve(new ParameterOverride("renderer", renderer));
    

    Canvas now has the right renderer injected. The canvas can use the renderer interface like this:

    internal interface ICanvas
    {
        void Draw();
    }
    
    public class Canvas : ICanvas
    {
        private readonly IRenderer _renderer;
    
        private readonly List _circles = new List();
        private readonly List _squares = new List();
    
        public Canvas(IRenderer renderer)
        {
            _renderer = renderer;
        }
    
        public void Draw()
        {
            foreach (var circle in _circles)
            {
                _renderer.Draw(circle);
            }
    
            foreach (var square in _squares)
            {
                _renderer.Draw(square);
            }
        }
    }
    

    Also the renderer should not be drawing the shape. The shape is responsible for drawing itself. This way you keep your code at the same spot. If you keep adding shapes the renderer file get huge. and you need to search for some shapes if you want to change code. Now everything is in the right place where it should be. The code now should look something like this:

    public interface IRenderer
    {
        void Draw(IShape shape);
    }
    
    public interface IShape
    {
        void Draw(IRenderer renderer);
    }
    
    public class Dx11Renderer : IRenderer
    {
        public void Draw(IShape shape)
        {
            shape.Draw(this);
        }
    }
    
    public class GlRenderer : IRenderer
    {
        public void Draw(IShape shape)
        {
            shape.Draw(this);
        }
    }
    
    public class Circle : IShape
    {
        public void Draw(IRenderer renderer)
        {
            if (renderer.GetType() == typeof(Dx11Renderer))
            {
                Console.WriteLine("Draw circle with DX11");
            }
    
            if (renderer.GetType() == typeof(GlRenderer))
            {
                Console.WriteLine("Draw circle with GL");
            }
        }
    }
    
    public class Square : IShape
    {
        public void Draw(IRenderer renderer)
        {
            if (renderer.GetType() == typeof(Dx11Renderer))
            {
                Console.WriteLine("Draw square with DX11");
            }
    
            if (renderer.GetType() == typeof(GlRenderer))
            {
                Console.WriteLine("Draw square with GL");
            }
        }
    }
    

    Hope this will help.

提交回复
热议问题