【问题标题】:Resolve IEnumerable with Autofac使用 Autofac 解决 IEnumerable
【发布时间】:2016-11-13 11:02:44
【问题描述】:

我正在尝试使用 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&lt;TRequest&gt; 放入构造函数时,它可以正常解析,但是当我将IEnumerable&lt;IValidator&lt;TRequest&gt;&gt; 放入时,它会失败,除了:

容器或服务定位器未正确配置或处理程序未在您的容器中注册。 ---> Autofac.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);
}

非常感谢任何建议!

【问题讨论】:

  • 您是否检查过您的过滤逻辑实际上返回了您期望的类型?在您的第二种选择中,您可以调试并看到 foreach 循环实际上是否遍历了您期望的所有类型?只是为了确保问题出在 Autofac 注册上,而不是类型查询。

标签: c# autofac mediatr


【解决方案1】:

首先,很高兴看到整个异常 - 包括内部异常 - 以及堆栈跟踪。

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");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 2016-08-15
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    相关资源
    最近更新 更多