我想注册一个在运行时自行解析的通用委托,但我找不到在泛型上执行此操作的方法。
鉴于代表看起来像这样:
public delegate TOutput Pipe<in TInput, out TOutput>(TInput input);
给定一个离散注册的代表,如下所示:
public class AnonymousPipe<TInput, TOutput>
{
public Pipe<TInput, TOutput> GetPipe(IContext context)
{...}
我想按照以下方式注册一个函数:
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);
我找不到在Autofac中提供泛型实现作为参数的方法 - 我可能只是遗漏了一些东西。我知道我可以通过通用对象或接口来做到这一点,但我想坚持代表的轻松。它使单元测试在注入这些时非常简单。
有什么想法?我现在不得不做离散注册(每种类型组合一个,没有泛型)。
答案 0 :(得分:4)
我只能提出注册源解决方案(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();
}
}
}
然后:
builder.RegisterSource(new PipeSource());
现在,我某些我无法将该代码输入网页并实际编译并运行,但它可能会接近:)