Autofac.Core.Registration.ComponentNotRegisteredException

本文关键字:ComponentNotRegisteredException Registration Core Autofac | 更新日期: 2023-09-27 18:15:50

我试图实现CQRS模式到我的应用程序。所以我发现如何从组装中注册所有命令处理程序:Autofac解析CQRS CommandDispatcher中的依赖

但是它对我不起作用。下面是代码:

        containerBuilder.RegisterAssemblyTypes(assembly)
            .AsClosedTypesOf(typeof(ICommandHandler<>));
        containerBuilder.RegisterAssemblyTypes(assembly)
            .AsClosedTypesOf(typeof(IQueryHandler<,>));

处理程序工厂
 public class CqrsHandlerFactory : ICqrsHandlerFactory
{
    private readonly IContainer container;
    public CqrsHandlerFactory(IContainer container)
    {
        this.container = container;
    }
    public ICommandHandler<TCommand> GetCommandHandler<TCommand>(TCommand command) where TCommand : class, ICommand
    {
        return container.Resolve<ICommandHandler<TCommand>>();
    }
    public IQueryHandler<TQuery, object> GetQueryHandler<TQuery>(TQuery query) where TQuery : class, IQuery
    {
        return container.Resolve<IQueryHandler<TQuery, object>>();
    }
}
总线

 public class CqrsBus : ICqrsBus
{
    private readonly ICqrsHandlerFactory cqrsHandlerFactory;
    public CqrsBus(ICqrsHandlerFactory cqrsHandlerFactory)
    {
        this.cqrsHandlerFactory = cqrsHandlerFactory;
    }
    public void ExecuteCommand(ICommand command)
    {
        var handler = cqrsHandlerFactory.GetCommandHandler(command);
        if (handler == null)
            throw new NotImplementedHandlerException(string.Format("Cannot find handler for {0}", command.GetType()));
        handler.Handle(command);
    }
    public TResult RunQuery<TResult>(IQuery query)
    {
        var handler = cqrsHandlerFactory.GetQueryHandler(query);
        if (handler == null)
            throw new NotImplementedHandlerException(string.Format("Cannot find handler for {0}", query.GetType()));
        return (TResult)handler.Handle(query);
    }
}

异常

类型为"autoface . core . registration"的异常。componentnoregisteredexception '在autoface .dll中发生,但未在用户代码中处理附加信息:请求的服务'PromocjeWsieciowkach.Messaging.Core. icommandhandler ' 1[[PromocjeWsieciowkach.Messaging.Core.]ICommand PromocjeWsieciowkach.Messaging。Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'尚未注册。要避免这种异常,要么注册一个组件来提供服务,要么使用IsRegistered()检查服务注册,要么使用ResolveOptional()方法来解析可选依赖项。

异常堆栈

在Autofac.ResolutionExtensions

。ResolveService(IComponentContext context, Service Service, IEnumerable 1 parameters) at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable 1参数)在PromocjeWsieciowkach.Messaging.Factories.CqrsHandlerFactory。GetCommandHandler[TCommand](TCommand命令)在C:'Users'Daniel'Desktop'PromocjeWsieciowkach'src'PromocjeWsieciowkach. messaging 'Factories'CqrsHandlersFactory.cs:第17行在PromocjeWsieciowkach.Messaging.Bus.CqrsBus。在C:'Users'Daniel'Desktop'PromocjeWsieciowkach'src'PromocjeWsieciowkach. messaging 'Bus'CqrsBus.cs中执行命令(ICommand命令):第17行在C:'Users'Daniel'Desktop'PromocjeWsieciowkach'src'PromocjeWsieciowkach'Controllers'PostController.cs中:第20行在lambda_method(闭包,对象,对象[])在Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__28.MoveNext ()

我做错了什么?

Autofac.Core.Registration.ComponentNotRegisteredException

您的代码和异常消息清楚地显示了问题。总之,您的异常消息解释如下:

请求的服务'ICommandHandler'尚未注册。

换句话说,您请求的是ICommandHandler<ICommand>而不是ICommandHandler<TestCommand>。可以在这里看到:

public void ExecuteCommand(ICommand command)
{
    var handler = cqrsHandlerFactory.GetCommandHandler(command);
    // ...
}
c#编译器对GetCommandHandler<T>调用应用了类型推断。下面的代码是实际的调用:
var handler = cqrsHandlerFactory.GetCommandHandler<ICommand>(command);

您应该将ICrqsBus.ExecuteCommand方法更改为以下内容:

public void ExecuteCommand<TCommand>(TCommand command)
{
    // You can merge the factory and your CqrsBus. Splitting them is useless.
    var handler = cqrsHandlerFactory.GetCommandHandler<TCommand>();
    // You don't need then null check; Autofac never returns null.
    handler.Handle(command);
}

如果你不能使ExecuteCommand方法泛型(例如,因为你不知道编译时的命令类型),你应该使用反射API构建泛型类型,如下所示:

public class CqrsBus : ICqrsBus
{
    private readonly IComponentContext context;
    public CqrsBus(IComponentContext context)
    {
        this.context = context;
    }
    public void ExecuteCommand(ICommand command)
    {
        Type handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType());
        dynamic handler = this.context.Resolve(handlerType);
        void handler.Execute((dynamic)command);
    }
}

同样值得注意的是,如果您使用nopcommerce并添加服务,如果您忘记在依赖注册器中添加服务,则会生成相同的错误。

builder.RegisterType<YourService>().As<IYourService>().InstancePerLifetimeScope();

我自己也遇到了这个,下面引用:

请求的服务'ICommandHandler'尚未注册。"

让我意识到依赖注册器。

感谢史蒂文

相关文章:
  • 没有找到相关文章