如何使用Unity将Type而不是实例注入构造函数

时间:2017-09-13 14:09:20

标签: c# dependency-injection unity-container

是否可以将类型注入构造函数而不是实例? 如果是这样,这是如何实现的?我想避免显式注册工厂方法或尽可能原地解析实例。

public interface IJob { }
public class TheJob : IJob { }

public interface IService
{
    string GetTypeDesc();
}

public class Service : IService
{
    private Type _jobType;

    public Service(Type jobType)
    {
        _jobType = jobType;
    }

    public string GetTypeDesc()
    {
        return _jobType.ToString();
    }
}

即使在使用显式构造函数定义注册类型时,Unity也希望将一个实例注入类型占位符。

Type jobType = typeof(TheJob);    
(new UnityContainer()).RegisterType<IService, Service>(new InjectionConstructor(jobType));

2 个答案:

答案 0 :(得分:1)

  

是否可以将类型注入构造函数而不是实例?

System.String是一种模糊类型,就像System.Int32InjectionConstructor这样的原始类型。它们被认为是不明确的,因为在运行时,该类型有多个(或许多)可能的值。这可以防止DI容器为您自动解析并注入此类值的实例。

这意味着您应该手动将值提供给Unity。这可以使用.RegisterType<IService, Service>(new InjectionConstructor(jobType)) 完成(正如您已经在做的那样):

InjectionFactory

或使用.Register<IService>(new InjectionFactory(c => new Service(jobType)))

{{1}}

答案 1 :(得分:1)

InjectionConstructor的构造函数接受一组对象。如果传递给InjectionConstructor(在数组中)的构造函数的对象类型是Type类型,则unity将尝试解析该类型,然后将结果传递给构造函数(&#39) ;服务`例如)。

例如,如果您使用new InjectionConstructor(typeof(IMyOtherService)),那么unity将期望Service的构造函数采用类型为IMyOtherService的实例,并将使用容器来解析此类型。换句话说,Type是您需要以特定方式处理的特殊情况。

要解决您的问题,您应该告诉Unity您传递的Type实际上是构造函数参数。你可以这样做:

new InjectionConstructor(new InjectionParameter(jobType))

这迫使团结将jobType视为构造函数参数。

有关详细信息,请参阅此处的InjectionParameterValue.ToParameter方法:https://github.com/unitycontainer/unity/blob/master/source/Src/Unity-CoreClr/Injection/InjectionParameterValue.cs