如何通过Autofac模块配置大众运输消费者

时间:2019-11-04 16:04:00

标签: c# module configuration autofac masstransit

如何在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字段,其中没有任何内容,只有启动应用程序中的内容。同样,当我发布事件时,位于那些模块中的所有使用者都没有使用它。这些事件仅在启动应用程序中使用。

1 个答案:

答案 0 :(得分:2)

在加载Autofac模块并将所有使用者都注册到容器之后,您可以使用以下内容注册使用者(和sagas)。

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