首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Autofac.Core.Registration.ComponentNotRegisteredException

Autofac.Core.Registration.ComponentNotRegisteredException
EN

Stack Overflow用户
提问于 2016-11-01 10:40:45
回答 2查看 15.2K关注 0票数 4

我试图在我的应用程序中实现CQRS模式。因此,我在这里找到了如何注册程序集中的所有命令处理程序:Autofac resolve dependency in CQRS CommandDispatcher

但对我来说不太好。以下是代码:

代码语言:javascript
复制
        containerBuilder.RegisterAssemblyTypes(assembly)
            .AsClosedTypesOf(typeof(ICommandHandler<>));

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

处理厂

代码语言:javascript
复制
 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>>();
    }
}

公共汽车

代码语言:javascript
复制
 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);
    }
}

异常

'Autofac.Core.Registration.ComponentNotRegisteredException‘类型的异常发生在Autofac.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上下文中,服务服务,( PromocjeWsieciowkach.Messaging.Factories.CqrsHandlerFactory.GetCommandHandlerTCommand in C:\Users\Daniel\Desktop\PromocjeWsieciowkach\src\PromocjeWsieciowkach.Messaging\Factories\CqrsHandlersFactory.cs:line 17 at PromocjeWsieciowkach.Messaging.Bus.CqrsBus.ExecuteCommand(ICommand命令) C:\Users\Daniel\Desktop\PromocjeWsieciowkach\src\PromocjeWsieciowkach.Messaging\Bus\CqrsBus.cs:line 17 at PromocjeWsieciowkach.Controllers.PostController.Index() in C:\Users\Daniel\Desktop\PromocjeWsieciowkach\src\PromocjeWsieciowkach\Controllers\PostController.cs:lambda_method第20行(关闭,对象,Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__28.MoveNext() ( Object[] )

那我做错什么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-01 12:51:19

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

请求的服务“ICommandHandler”尚未注册。

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

代码语言:javascript
复制
public void ExecuteCommand(ICommand command)
{
    var handler = cqrsHandlerFactory.GetCommandHandler(command);
    // ...
}

C#编译器将类型推断应用于GetCommandHandler<T>调用。下面的代码是实际调用:

代码语言:javascript
复制
var handler = cqrsHandlerFactory.GetCommandHandler<ICommand>(command);

应该将ICrqsBus.ExecuteCommand方法更改为:

代码语言:javascript
复制
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构建泛型类型,如下所示:

代码语言:javascript
复制
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);
    }
}
票数 7
EN

Stack Overflow用户

发布于 2017-11-08 02:12:18

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

代码语言:javascript
复制
builder.RegisterType<YourService>().As<IYourService>().InstancePerLifetimeScope();

我自己也发现了这一点,下面的引语是:

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

让我意识到了受抚养登记员的事。

谢谢史蒂文

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40358433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档