简体   繁体   English

如何通过 Autofac 模块配置 Masstransit 消费者

[英]How to Configure Masstransit Consummers by Autofac Modules

How to register Masstransit consumers in Autofac modules.如何在 Autofac 模块中注册 Masstransit 消费者。

I have this code:我有这个代码:

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

And in another Module I have this code:在另一个模块中,我有以下代码:

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

But the Consumers located in Modue assembly is not found by Masstransit.但是 Masstransit 找不到位于 Modue 组件中的消费者。 Please help请帮忙

EDIT: I have multiple assemblies (modules) that are not directly referenced by the starting project.编辑:我有多个程序集(模块)没有被起始项目直接引用。 The assemblies are loaded at the application startup using MEF from a /Modules subfolder.程序集在应用程序启动时使用 /Modules 子文件夹中的 MEF 加载。 The consumers are located in those modules.消费者位于这些模块中。 I use Autofac integration with MEF to load Autofac Modules into Autofac configuration.我使用 Autofac 与 MEF 的集成将 Autofac 模块加载到 Autofac 配置中。 When I say that Mass transit can't find consumers, I mean this: when I put a breakpoint ate the line当我说公共交通找不到消费者时,我的意思是:当我设置断点时吃掉了这条线

configurator.AddBus(...)配置器.AddBus(...)

and inspect the configurator._consumerRegistrations field, there are none in it, only the ones from the starting application.并检查 configurator._consumerRegistrations 字段,其中没有,只有来自启动应用程序的字段。 Also when I publish events, none of the consumers located in those modules are consuming it.此外,当我发布事件时,位于这些模块中的消费者都没有使用它。 The events are only consumed in the starting application.这些事件仅在启动应用程序中使用。

After the Autofac modules are loaded, and all of the consumers are registered in the container, you can use the following to register the consumers (and sagas).加载 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<>)));
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM