用统一的其他构造函数解析参数

时间:2015-11-19 10:39:19

标签: c# dependency-injection unity-container

我使用Unity并注入所有依赖项。让我们说我有一个Manager类,如此

public class Manager : IManager
{
    public Manager(IRepository repository, string customerName) { }
}

还有一个类库:

public class Repository : IRepository
{
    public Repository(string customerName) { }
}

我正在使用WCF,每次请求都会解析一次管理器和存储库。我在服务启动时注册了所有类型,但在启动时我不知道" customerName" -parameter。这将作为参数传递给WCF服务。哪个会像这样解决经理:

public class Service
{
    private IUnityContainer _container;

    public Service(IUnityContainer container)
    {
        _container = container;
    }

    public void ServiceCall(string customerName)
    {
        var manager = _container.Resolve<IManager<T>>(
            new ParameterOverrides { { "customerName", customerName} });
        manager.DoSomething();
    }
}

这样我可以在每次请求时将customerName - 参数注入管理器。这很好用。但是现在我还需要将它注入存储库。 有没有办法将customerName注入到存储库类中?

我知道我可以稍后手动设置它,但我想在构造函数中使用它。此外,我不希望服务了解存储库,因此我不想手动覆盖该参数。

我可以使用管理器中构造函数中的容器来解析IRepository,但我只是在可能的情况下注入它。

1 个答案:

答案 0 :(得分:1)

  

我在服务启动时注册了所有类型,但在启动时我没有   知道&#34; customerName&#34; -parameter

换句话说,您的customerName参数是运行时数据。在组件期间将运行时数据注入组件中。初始化is an anti-pattern

您的问题有两种可能的解决方案,但在您的情况下,最可能的解决方案是通过公共API传递参数,如下所示:

public class Service
{
    private readonly IManager _manager;

    public Service(IManager manager) {
        _manager = manager;
    }

    public void ServiceCall(string customerName) {
        _manager.DoSomething(customerName);
    }
}

此处更改了IManager界面,以便customerName通过DoSomething方法传递。因为在构造期间不再需要运行时值,所以不需要将Unity容器注入Service(这是Service Locator anti-pattern的一种形式)。

对于第二种选择,请阅读this article