在WebAPI操作中Unity实例注入实例

时间:2015-06-30 11:11:14

标签: unity-container

我对此感到困惑,我想知道解决这个问题的最佳方法是什么。我有一个WebApi控制器,我想注入ICommand实例,但是一旦检查Post请求数据,我就知道我需要什么实例。我将举一个例子来说明一点,但我的问题也适用于你接收事件参数的Winform事件,并且根据这个事件arg你想要注入不同的实现。

public class TestController : ApiController
{
    public object Post(int id)
    {
        ICommand command = null;

        if(id = 1)
        {
            command = new Id1Command();
        }
        else
        {
            command = new Id2Command();
        }

        return new object();
    }
}

我唯一能想到的是创建一个工厂,接受统一容器作为参数,并在工厂内调用container.Resolve与命名实例。

我的问题在于,我被告知你不应该在你的作文根之外注册或解决,这违反了良好的做法(根据Mark Seemann的说法)。我一般都在寻找这个问题的最佳设计。

1 个答案:

答案 0 :(得分:0)

我会使用CommandFactory并将其传递给TestController:

public class TestController : ApiController
{
    private readonly ICommandFactory mCommandFactory;

    public TestController(ICommandFactory CommandFactory)
    {
        mCommandFactory = CommandFactory;
    }

    public object Post(int id)
    {
        ICommand command = null;

        if(id = 1)
        {
            command = CommandFactory.CreateId1Command();
        }
        else
        {
            command = CommandFactory.CreateId2Command();
        }

        return new object();
    }
}

现在你必须确保Unity正在创建TestController。为此,您必须实现,配置和设置IDependencyResolver。检查Dependency Injection in ASP.NET Web API 2

编辑您的评论:

对于这种情况,您可以使用带有int:

的仿函数来使用自动生成器
public class TestController : ApiController
{
    private readonly Func<int, ICommand> mCommandFactory

    public TestController(Func<int, ICommand> CommandFactory)
    {
        mCommandFactory = CommandFactory;
    }

    public object Post(int id)
    {
        var command mCommandFactory(id);

        return new object();
    }
}

注册应如下所示:

container.RegisterType<Func<int, ICommand>>(new InjectionFactory(
    c => new Func<int, ICommand>(
                id =>
                {
                    if (id == 1)
                    {
                        return new Command();
                    }
                    else
                    {
                        return new Command2();
                    }
                })));

注意:您仍然需要设置DependencyResolver!