用来自其他构造函数的参数与统一解析 [英] Resolve with parameter from other constructor with unity

查看:147
本文介绍了用来自其他构造函数的参数与统一解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Unity并注入我的所有依赖项。让我们说,我有一个经理类如下

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

还有一个仓库类,如:

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

我正在使用WCF并将解析经理和存储库一次请求。我在服务启动时注册我的所有类型,但在启动时,我不知道customerName参数。这将作为参数传递给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 -p参数到每个请求的管理器中。这工作正常但是现在我还需要将其注入到存储库中。 有没有办法将 customerName 注入到存储库类中?



我知道我以后可以手动设置,但我想在构造函数中进行设置。此外,我不希望服务知道存储库,所以我不想手动覆盖该参数。



我可以解决 IRepository 与管理器中的构造函数中的容器相关联,但如果可行,我宁愿只注入它。

解决方案


我在服务启动时注册了所有的类型,但是在启动时我不会
知道customerName-parameter


换句话说,您的 customerName 参数是运行时数据。在组件初始化期间将运行时数据注入组件是一种反模式



您的问题有两种可能的解决方案,但在您的情况下,最有可能的解决方案是通过公共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 (这是一种服务定位器反模式)。



对于第二个选项,请阅读本文


I'm using Unity and inject all my dependencies. Let's say that I have a Manager class like so

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

And a repository class like:

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

I'm using WCF and will resolve the manager and the repository once per request. I register all my types at service startup, but at startup i do not know the "customerName"-parameter. This will be passed as a parameter to the WCF-service. Which will resolve the manager like this:

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();
    }
}

This way I can inject the customerName-parameter into the manager on each request. This works fine. But now I also need to inject it to the repository. Is there any way to inject the customerName to the repository-class as well?

I know I can set it manually later, but I would like to have this in the constructor. Also, I don't want the Service to know about the Repository, so I don't want to manually override that parameter.

I could resolve the IRepository with the container in the constructor in the Manager, but i rather just inject it if it's possible.

解决方案

I register all my types at service startup, but at startup i do not know the "customerName"-parameter

In other words, your customerName parameter is runtime data. Injecting runtime data into components during the components' initialization is an anti-pattern.

There are two possible solutions to your problem, but in your your case, the most likely solution is to pass through the parameter through the public API as follows:

public class Service
{
    private readonly IManager _manager;

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

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

Here the IManager interface is changed so that the customerName is passed through the DoSomething method. Because the runtime value isn't needed anymore during construction, there is no need to inject the Unity container into the Service (which is a form of the Service Locator anti-pattern).

For the second option, please read this article.

这篇关于用来自其他构造函数的参数与统一解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆