为我的Unity容器注册一个类型时,我需要将调用类的类型传入已解析对象的构造函数。
这是我将一些接口注入构造函数的类。
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期望构造函数中的Type:
public class SomeClass2
{
public SomeClass2(Type type)
{
//...
}
}
这是我设置容器的Unity bootstrap类。现在,对于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方法中的其他方式)执行此操作?
答案 0 :(得分:2)
如果您可以控制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;
}
}
答案 1 :(得分:0)
1)如果SomeClass2
始终使用类型ProcessingService
,那么您可以将类型参数直接传递到InjectionFactory
container.RegisterType<ISomeClass2>(new InjectionFactory(_ =>
{
return new SomeClass2(typeof(ProcessingService));
}));
2)否则,如果类型参数在整个应用程序中不同,则应考虑向接口ISomeClass2
添加注册方法,并在构造函数中注册类型以强调依赖性/变体。
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());
}
}
答案 2 :(得分:0)
如果您不控制ProcessingService
(或SomeClass2的其他使用者),您可以自定义这些使用者的注册。这种方法更具侵入性,因为您必须为每个消费者创建一个注射工厂。
container
.RegisterType<IProcessingService, ProcessingService>(new InjectionFactory((c, type, name) =>
{
return new ProcessingService(c.Resolve<ISomeClass1>(), new SomeClass2(type));
}));