Resolve IEnumerable with Autofac
本文关键字:Autofac with IEnumerable Resolve | 更新日期: 2023-09-27 18:17:45
我正在尝试用Mediatr和Autofac构建一个中介管道,但我正在努力解决Autofac验证器的集合。
public class MediatorPipeline<TRequest, TResponse>
: IAsyncRequestHandler<TRequest, TResponse> where TRequest : IAsyncRequest<TResponse>
{
private readonly IAsyncRequestHandler<TRequest, TResponse> _inner;
private readonly IEnumerable<IValidator<TRequest>> _validators;
public MediatorPipeline(IAsyncRequestHandler<TRequest, TResponse> inner,
IEnumerable<IValidator<TRequest>> validators)
{
_inner = inner;
_validators = validators;
}
...
}
当我把IValidator<TRequest>
放入构造函数时,它解析得很好,但是当我把IEnumerable<IValidator<TRequest>>
放入构造函数时,它失败了,除了:
这是我的注册码:容器或服务定位器未正确配置或处理程序未在容器中注册。--> autoface . core . dependencyresolutionexception:在激活特定注册时发生错误。
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.IsClosedTypeOf(typeof(IValidator<>)))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
我用这个替代注册得到了相同的结果:
var openGenericType = typeof(IValidator<>);
var query = from type in assembly.GetTypes().Where(c => !(c.GetTypeInfo().IsAbstract || c.GetTypeInfo().IsGenericTypeDefinition))
let interfaces = type.GetInterfaces()
let genericInterfaces = interfaces.Where(i => i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == openGenericType)
let matchingInterface = genericInterfaces.FirstOrDefault()
where matchingInterface != null
select new { matchingInterface, type };
foreach (var pair in query)
{
builder.RegisterType(pair.type).As(pair.matchingInterface);
}
任何建议都非常感谢!
首先,很高兴看到整个异常-包括内部异常-与堆栈跟踪。
Autofac暴露了一个方便的扩展方法,AsClosedTypesOf
,您可以这样使用:
builder
.RegisterAssemblyTypes(ThisAssembly)
.AsClosedTypesOf(typeof(IValidator<>))
.InstancePerLifetimeScope();
这将为您完成工作,因此您不必深入思考注册验证器。
然后你需要在上面注册你的处理程序和装饰器:
builder
.RegisterAssemblyTypes(ThisAssembly)
.AsClosedTypesOf(typeof(IAsyncRequestHandler<,>), "base-handler")
.InstancePerDependency();
builder.RegisterGenericDecorator(
typeof(MediatorPipeline<,>),
typeof(IAsyncRequestHandler<,>),
"base-handler");