在依赖项解析期间获取 class 类型
Get class type during dependency resoluton
为我的 unity 容器注册类型时,我需要将调用 class 的类型传递到已解析对象的构造函数中。
这是 class 我将一些接口注入构造函数的地方。
namespace MyNamespace
{
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, ISomeClass2 someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
}
}
}
SomeClass2 期望在构造函数中输入:
public class SomeClass2
{
public SomeClass2(Type type)
{
//...
}
}
这是我的 unity bootstrap class 我设置容器的地方。现在,对于ISomeClass2,解析为SomeClass2时,需要传入ProcessingService的类型。
namespace MyNamespace
{
public class UnityBootstrap : IUnityBootstrap
{
public IUnityContainer Configure(IUnityContainer container)
{
return container
.RegisterType<ISomeClass1, SomeClass1>()
.RegisterType<ISomeClass2>(new InjectionFactory(fac =>
{
// IMethodBase.GetCurrentMethod().DeclaringType is returning MyNamespace.UnityBootstrap
// whereas I need to get MyNamespace.ProcessingService
return new SomeClass2(MethodBase.GetCurrentMethod().DeclaringType);
}));
}
}
}
有没有办法使用 InjectionFactory(或我的 Configure 方法中的其他方式)来做到这一点?
恕我直言,这个问题有两种观点:
1) 如果 SomeClass2
将始终使用类型 ProcessingService
那么您可以将类型参数直接传递到 InjectionFactory
container.RegisterType<ISomeClass2>(new InjectionFactory(_ =>
{
return new SomeClass2(typeof(ProcessingService));
}));
2) 否则,如果类型参数在整个应用程序中不同,您应该考虑向接口 ISomeClass2
添加注册方法并从构造函数中注册类型以强调 dependency/variation.
public interface ISomeClass2
{
void DoSomething();
void RegisterProcessingServiceType(Type processingServiceType);
}
public class SomeClass2 : ISomeClass2
{
private Type _type;
public void DoSomething()
{
if(_type == null)
throw InvalidOperationException("Register processing service type before doing stuff.");
// actually do something
}
public void RegisterProcessingServiceType(Type serviceType)
{
_type = serviceType;
}
}
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, ISomeClass2 someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
this.someClass2.RegisterProcessingServiceType(this.GetType());
}
}
如果您可以控制 ProcessingService
,您可以围绕 SomeClass2
创建一个通用包装器,然后使用开放式泛型注册它。但这需要您修改 ProcessingService
.
的构造函数
public interface IGenericSomeClass2<T>: ISomeClass2 {}
public class GenericSomeClass2<T>: IGenericSomeClass2<T>
{
private readonly ISomeClass2 someClass2;
public GenericSomeClass2()
{
this.someClass2 = new SomeClass2(typeof(T));
}
// Pass-through implementation
}
public IUnityContainer Configure(IUnityContainer container)
{
return container
.RegisterType<ISomeClass1, SomeClass1>()
.RegisterType(typeof(IGenericSomeClass2<>), typeof(GenericSomeClass2<>));
}
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, IGenericSomeClass2<ProcessingService> someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
}
}
如果您不控制 ProcessingService
(或 SomeClass2 的其他消费者),您可以自定义这些消费者的注册。这种方法更具侵入性,因为您必须为每个消费者创建一个注入工厂。
container
.RegisterType<IProcessingService, ProcessingService>(new InjectionFactory((c, type, name) =>
{
return new ProcessingService(c.Resolve<ISomeClass1>(), new SomeClass2(type));
}));
为我的 unity 容器注册类型时,我需要将调用 class 的类型传递到已解析对象的构造函数中。
这是 class 我将一些接口注入构造函数的地方。
namespace MyNamespace
{
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, ISomeClass2 someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
}
}
}
SomeClass2 期望在构造函数中输入:
public class SomeClass2
{
public SomeClass2(Type type)
{
//...
}
}
这是我的 unity bootstrap class 我设置容器的地方。现在,对于ISomeClass2,解析为SomeClass2时,需要传入ProcessingService的类型。
namespace MyNamespace
{
public class UnityBootstrap : IUnityBootstrap
{
public IUnityContainer Configure(IUnityContainer container)
{
return container
.RegisterType<ISomeClass1, SomeClass1>()
.RegisterType<ISomeClass2>(new InjectionFactory(fac =>
{
// IMethodBase.GetCurrentMethod().DeclaringType is returning MyNamespace.UnityBootstrap
// whereas I need to get MyNamespace.ProcessingService
return new SomeClass2(MethodBase.GetCurrentMethod().DeclaringType);
}));
}
}
}
有没有办法使用 InjectionFactory(或我的 Configure 方法中的其他方式)来做到这一点?
恕我直言,这个问题有两种观点:
1) 如果 SomeClass2
将始终使用类型 ProcessingService
那么您可以将类型参数直接传递到 InjectionFactory
container.RegisterType<ISomeClass2>(new InjectionFactory(_ =>
{
return new SomeClass2(typeof(ProcessingService));
}));
2) 否则,如果类型参数在整个应用程序中不同,您应该考虑向接口 ISomeClass2
添加注册方法并从构造函数中注册类型以强调 dependency/variation.
public interface ISomeClass2
{
void DoSomething();
void RegisterProcessingServiceType(Type processingServiceType);
}
public class SomeClass2 : ISomeClass2
{
private Type _type;
public void DoSomething()
{
if(_type == null)
throw InvalidOperationException("Register processing service type before doing stuff.");
// actually do something
}
public void RegisterProcessingServiceType(Type serviceType)
{
_type = serviceType;
}
}
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, ISomeClass2 someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
this.someClass2.RegisterProcessingServiceType(this.GetType());
}
}
如果您可以控制 ProcessingService
,您可以围绕 SomeClass2
创建一个通用包装器,然后使用开放式泛型注册它。但这需要您修改 ProcessingService
.
public interface IGenericSomeClass2<T>: ISomeClass2 {}
public class GenericSomeClass2<T>: IGenericSomeClass2<T>
{
private readonly ISomeClass2 someClass2;
public GenericSomeClass2()
{
this.someClass2 = new SomeClass2(typeof(T));
}
// Pass-through implementation
}
public IUnityContainer Configure(IUnityContainer container)
{
return container
.RegisterType<ISomeClass1, SomeClass1>()
.RegisterType(typeof(IGenericSomeClass2<>), typeof(GenericSomeClass2<>));
}
internal class ProcessingService: IProcessingService
{
private readonly ISomeClass1 someClass1;
private readonly ISomeClass2 someClass2;
public ProcessingService(ISomeClass1 someClass1, IGenericSomeClass2<ProcessingService> someClass2)
{
this.someClass1 = someClass1;
this.someClass2 = someClass2;
}
}
如果您不控制 ProcessingService
(或 SomeClass2 的其他消费者),您可以自定义这些消费者的注册。这种方法更具侵入性,因为您必须为每个消费者创建一个注入工厂。
container
.RegisterType<IProcessingService, ProcessingService>(new InjectionFactory((c, type, name) =>
{
return new ProcessingService(c.Resolve<ISomeClass1>(), new SomeClass2(type));
}));