如何使用 Unity 将类型而不是实例注入构造函数
How to inject a Type instead of an instance into a constructor using Unity
是否可以将类型而不是实例注入到构造函数中?
如果是这样,这是如何实现的?如果可能,我想避免显式注册工厂方法或就地解析实例。
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));
Is it possible to inject a type into a constructor instead of an instance?
A System.Type
是一种二义性类型,就像 System.String
和 System.Int32
等基本类型一样。它们被认为是不明确的,因为在运行时该类型有多个(或许多)可能的值。这可以防止 DI 容器自动为您解析和注入此类值的实例。
这意味着您应该手动将值提供给 Unity。这可以使用 InjectionConstructor
来完成(正如您已经在做的那样):
.RegisterType<IService, Service>(new InjectionConstructor(jobType))
或使用 InjectionFactory
:
.Register<IService>(new InjectionFactory(c => new Service(jobType)))
InjectionConstructor
的构造函数接受一个对象数组。如果传递给 InjectionConstructor
的构造函数(在数组中)的对象类型是 Type
类型,unity 将尝试解析该类型,然后将结果传递给构造函数('Service`例如)。
例如,如果您使用 new InjectionConstructor(typeof(IMyOtherService))
,那么 unity 将期望 Service
的构造函数采用类型 IMyOtherService
的实例,并将使用容器来解析此类。换句话说,Type
是一种特殊情况,您需要以特定方式处理。
要解决您的问题,您应该告诉 Unity 您传递的 Type
实际上是一个构造函数参数。你可以这样做:
new InjectionConstructor(new InjectionParameter(jobType))
这会强制 unity 将 jobType
视为构造函数参数。
有关详细信息,请参阅此处的 InjectionParameterValue.ToParameter
方法:https://github.com/unitycontainer/unity/blob/master/source/Src/Unity-CoreClr/Injection/InjectionParameterValue.cs
是否可以将类型而不是实例注入到构造函数中? 如果是这样,这是如何实现的?如果可能,我想避免显式注册工厂方法或就地解析实例。
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));
Is it possible to inject a type into a constructor instead of an instance?
A System.Type
是一种二义性类型,就像 System.String
和 System.Int32
等基本类型一样。它们被认为是不明确的,因为在运行时该类型有多个(或许多)可能的值。这可以防止 DI 容器自动为您解析和注入此类值的实例。
这意味着您应该手动将值提供给 Unity。这可以使用 InjectionConstructor
来完成(正如您已经在做的那样):
.RegisterType<IService, Service>(new InjectionConstructor(jobType))
或使用 InjectionFactory
:
.Register<IService>(new InjectionFactory(c => new Service(jobType)))
InjectionConstructor
的构造函数接受一个对象数组。如果传递给 InjectionConstructor
的构造函数(在数组中)的对象类型是 Type
类型,unity 将尝试解析该类型,然后将结果传递给构造函数('Service`例如)。
例如,如果您使用 new InjectionConstructor(typeof(IMyOtherService))
,那么 unity 将期望 Service
的构造函数采用类型 IMyOtherService
的实例,并将使用容器来解析此类。换句话说,Type
是一种特殊情况,您需要以特定方式处理。
要解决您的问题,您应该告诉 Unity 您传递的 Type
实际上是一个构造函数参数。你可以这样做:
new InjectionConstructor(new InjectionParameter(jobType))
这会强制 unity 将 jobType
视为构造函数参数。
有关详细信息,请参阅此处的 InjectionParameterValue.ToParameter
方法:https://github.com/unitycontainer/unity/blob/master/source/Src/Unity-CoreClr/Injection/InjectionParameterValue.cs