是否有可能在autofac中注册一个开放的通用委托? [英] Is it possible to register an open generic delegate in autofac?
问题描述
我想注册一个可以在运行时自行解决的泛型委托,但是我找不到在泛型上做到这一点的方法。
给定一个看起来像这样的委托:
public delegate TOutput Pipe
给出一个离散注册的委托,如下所示:
public class AnonymousPipe< TInput,TOutput>
{
public Pipe< TInput,TOutput> GetPipe(IContext上下文)
{...}
我想注册一个函数这个行:
builder.RegisterGeneric(typeof(Pipe<,>))。As(ctx =>
{
var typeArray = ctx.RequestedType.GetGenericArguments();
//这可以被记忆
var pipeDefinition = ctx.Resolve(typeof(AnonymousPipe<,>)。MakeGenericType (typeArray));
return pipeDefinition.GetPipe(ctx);
我无法找到在Autofac中提供通用实现作为参数的方法 - 我可能只是缺少一些东西,我知道我可以通过一个通用的对象或接口来实现,但我想坚持一个委托的轻松。它使得单元测试在注入这些元素时变得非常简单。
有什么想法?我现在必须做离散注册(每个类型组合一个,没有泛型)。
我可以o只需拿出注册源解决方案(Autofac中的通用锤子)。
class PipeSource:IRegistrationSource
{
public bool IsAdapterForIndividualComponents {get {return true; }}
public IEnumerable< IComponentRegistration> RegistrationsFor(
Service service,
Func< Service,IEnumerable< IComponentRegistration>> registrationAccessor)
{
var swt = service as IServiceWithType;
if(swt == null ||!swt.ServiceType.IsGenericType)
yield break;
var def = swt.ServiceType.GetGenericTypeDefinition();
if(def!= typeof(Pipe<,>))
yield break;
var anonPipeService = swt.ChangeType(
typeof(AnonymousPipe<,>)。MakeGenericType(
swt.ServiceType.GetGenericArguments()));
var getPipeMethod = anonPipeService.ServiceType.GetMethod(GetPipe);
foreach(registerAccessor(anonPipeService)中的var anonPipeReg)
{
yield return RegistrationBuilder.ForDelegate((c,p)=> {
var anon = c .ResolveComponent(anonPipeReg,p);
return getPipeMethod.Invoke(anon,null);})
.As(service)
.Targeting(anonPipeReg)
.CreateRegistration() ;
}
}
}
然后:
builder.RegisterSource(new PipeSource());
现在,我确定我无法输入该代码进入一个网页并让它实际编译和运行,但它可能会接近:)
I want to register a generic delegate that resolves itself at runtime, but I cannot find a way to do this on generics.
Given a delegate that looks like this:
public delegate TOutput Pipe<in TInput, out TOutput>(TInput input);
And given a discretely registered delegate that look like this:
public class AnonymousPipe<TInput, TOutput>
{
public Pipe<TInput, TOutput> GetPipe(IContext context)
{...}
I want to register a function along the lines of this:
builder.RegisterGeneric(typeof(Pipe<,>)).As(ctx =>
{
var typeArray = ctx.RequestedType.GetGenericArguments();
// this can be memoized
var pipeDefinition = ctx.Resolve(typeof(AnonymousPipe<,>).MakeGenericType(typeArray));
return pipeDefinition.GetPipe(ctx);
I cannot find a way to provide an implementation of the generic as a parameter in Autofac - I may just be missing something. I know I can do this through a generic object or interface, but I want to stick with the lightness of a delegate. It makes unit testing super simple on the injection of these.
Any thoughts? I am having to do discrete registrations at the moment(one per type combination and no generics).
I can only come up with the registration source solution (the universal hammer in Autofac.)
class PipeSource : IRegistrationSource
{
public bool IsAdapterForIndividualComponents { get { return true; } }
public IEnumerable<IComponentRegistration> RegistrationsFor(
Service service,
Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
var swt = service as IServiceWithType;
if (swt == null || !swt.ServiceType.IsGenericType)
yield break;
var def = swt.ServiceType.GetGenericTypeDefinition();
if (def != typeof(Pipe<,>))
yield break;
var anonPipeService = swt.ChangeType(
typeof(AnonymousPipe<,>).MakeGenericType(
swt.ServiceType.GetGenericArguments()));
var getPipeMethod = anonPipeService.ServiceType.GetMethod("GetPipe");
foreach (var anonPipeReg in registrationAccessor(anonPipeService))
{
yield return RegistrationBuilder.ForDelegate((c, p) => {
var anon = c.ResolveComponent(anonPipeReg, p);
return getPipeMethod.Invoke(anon, null); })
.As(service)
.Targeting(anonPipeReg)
.CreateRegistration();
}
}
}
Then:
builder.RegisterSource(new PipeSource());
Now, I'm certain that I can't type that code into a web page and have it actually compile and run, but it might come close :)
这篇关于是否有可能在autofac中注册一个开放的通用委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!