Autofac允许您使用RegisterGeneric方法注册泛型类型。
我想注册ImmutableArray<T>。
我想要的语义与IEnumerable<T>相同-即Autofac应该创建一个包含所有T注册的ImmutableArray<T>实例。
如果这是非通用的,那就很简单了:
builder.Register<ImmutableArray<string>>(c => c.Resolve<IEnumerable<string>>().ToImmutableArray());然而,对于泛型类型,我看不到任何方法。
发布于 2020-01-10 17:26:41
使用lambda表达式注册泛型方法没有简单的方法。为此,您需要使用具有泛型类型操作的IRegistrationSource。
大概是这样的:
public class ImmutableArrayRegistrationSource : IRegistrationSource
{
public bool IsAdapterForIndividualComponents => false;
private static MethodInfo toImmutableArrayMethod =
typeof(ImmutableArray)
.GetMethods()
.Where(m => m.Name == nameof(ImmutableArray.ToImmutableArray)
&& m.GetParameters().Any(p => p.ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
.FirstOrDefault();
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
IServiceWithType typedService = service as IServiceWithType;
if (typedService != null && typedService.ServiceType.IsClosedTypeOf(typeof(ImmutableArray<>)))
{
Type elementType = typedService.ServiceType.GetGenericArguments()[0];
IComponentRegistration r = RegistrationBuilder.ForDelegate(typedService.ServiceType, (c, p) =>
{
Object elements = c.Resolve(typeof(IEnumerable<>).MakeGenericType(elementType));
Object immutableArray = toImmutableArrayMethod.MakeGenericMethod(elementType)
.Invoke(null, new Object[] { elements });
return immutableArray;
}).As(service)
.CreateRegistration();
yield return r;
}
yield break;
}
}然后注册您的注册源:
builder.RegisterSource<ImmutableArrayRegistrationSource>();https://stackoverflow.com/questions/59623353
复制相似问题