【问题标题】:How to Configure Masstransit Consummers by Autofac Modules如何通过 Autofac 模块配置 Masstransit 消费者
【发布时间】:2019-11-04 16:04:00
【问题描述】:

如何在 Autofac 模块中注册 Masstransit 消费者。

我有这个代码:

 builder.AddMassTransit(configurator =>
        {
            configurator.AddConsumers(ThisAssembly);
            //Bus
            configurator.AddBus(c => c.Resolve<IBusFactory>().CreateBus());
        });

在另一个模块中我有这个代码:

public class AutofacModule: Module
{
    public override void Load(ContainerBuilder builder)
    {    
        builder.RegisterConsumers(ThisAssembly);
    }
}

但是 Masstransit 找不到位于 Modue 组件中的消费者。 请帮忙

编辑: 我有多个程序集(模块)没有被起始项目直接引用。程序集在应用程序启动时使用 /Modules 子文件夹中的 MEF 加载。消费者位于这些模块中。我使用 Autofac 与 MEF 的集成将 Autofac 模块加载到 Autofac 配置中。 当我说公共交通找不到消费者时,我的意思是: 当我放断点时吃掉了这条线

configurator.AddBus(...)

并检查 configurator._consumerRegistrations 字段,其中没有,只有来自启动应用程序的字段。此外,当我发布事件时,位于这些模块中的消费者都没有使用它。这些事件仅在启动应用程序中使用。

【问题讨论】:

  • 您不需要像第二个代码 sn-p 中那样注册消费者,.AddConsumers() 方法会为您注册消费者。不清楚您所说的“大众运输未找到消费者”是什么意思,您能否使用您遇到的错误?此外,如果您打算使用参数,请不要使用_ =&gt; { },请为参数命名。这可能会导致问题。
  • 我添加了更多细节并重命名了_。到配置器。

标签: c# module configuration autofac masstransit


【解决方案1】:

Autofac 模块加载完成后,所有消费者都注册到容器中,你可以使用以下方法注册消费者(和 saga)。

    public static void AddConsumersFromContainer(this IRegistrationConfigurator configurator, IComponentContext context)
    {
        var consumerTypes = context.FindTypes(IsConsumerOrDefinition);
        configurator.AddConsumers(consumerTypes);
    }

    public static void AddSagasFromContainer(this IRegistrationConfigurator configurator, IComponentContext context)
    {
        var sagaTypes = context.FindTypes(IsSagaOrDefinition);
        configurator.AddSagas(sagaTypes);
    }

    static Type[] FindTypes(this IComponentContext context, Func<Type, bool> filter)
    {
        return context.ComponentRegistry.Registrations
            .SelectMany(r => r.Services.OfType<IServiceWithType>(), (r, s) => (r, s))
            .Where(rs => filter(rs.s.ServiceType))
            .Select(rs => rs.s.ServiceType)
            .ToArray();
    }

    /// <summary>
    /// Returns true if the type is a consumer, or a consumer definition
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static bool IsConsumerOrDefinition(Type type)
    {
        Type[] interfaces = type.GetTypeInfo().GetInterfaces();

        return interfaces.Any(t => t.HasInterface(typeof(IConsumer<>)) || t.HasInterface(typeof(IConsumerDefinition<>)));
    }

    /// <summary>
    /// Returns true if the type is a saga, or a saga definition
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static bool IsSagaOrDefinition(Type type)
    {
        Type[] interfaces = type.GetTypeInfo().GetInterfaces();

        if (interfaces.Contains(typeof(ISaga)))
            return true;

        return interfaces.Any(t => t.HasInterface(typeof(InitiatedBy<>))
            || t.HasInterface(typeof(Orchestrates<>))
            || t.HasInterface(typeof(Observes<,>))
            || t.HasInterface(typeof(ISagaDefinition<>)));
    }

【讨论】:

  • 我使用它:builder.AddMassTransit(configurator => { configurator.AddConsumersFromContainer(); //Bus configurator.AddBus(c => c.Resolve().CreateBus() ); });但是我从哪里获得 ComponentContext?
  • 你刚才引用的 .AddBus() 中的c
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 1970-01-01
  • 2022-07-22
  • 1970-01-01
相关资源
最近更新 更多