如何通过 Autofac 模块配置公共交通消费者
How to Configure Masstransit Consummers by Autofac Modules
如何在 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 组件中的消费者。
请帮忙
编辑:
我有多个程序集(模块)未被起始项目直接引用。这些程序集是在应用程序启动时使用 MEF 从 /Modules 子文件夹中加载的。消费者位于这些模块中。我使用 Autofac 与 MEF 的集成来将 Autofac 模块加载到 Autofac 配置中。
当我说公共交通找不到消费者时,我的意思是:
当我放置一个断点时,吃了一行
configurator.AddBus(...)
并检查 configurator._consumerRegistrations 字段,其中有 none,只有启动应用程序中的那些。此外,当我发布事件时,位于这些模块中的 none 消费者正在使用它。事件仅在启动应用程序中使用。
加载 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<>)));
}
如何在 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 组件中的消费者。 请帮忙
编辑: 我有多个程序集(模块)未被起始项目直接引用。这些程序集是在应用程序启动时使用 MEF 从 /Modules 子文件夹中加载的。消费者位于这些模块中。我使用 Autofac 与 MEF 的集成来将 Autofac 模块加载到 Autofac 配置中。 当我说公共交通找不到消费者时,我的意思是: 当我放置一个断点时,吃了一行
configurator.AddBus(...)
并检查 configurator._consumerRegistrations 字段,其中有 none,只有启动应用程序中的那些。此外,当我发布事件时,位于这些模块中的 none 消费者正在使用它。事件仅在启动应用程序中使用。
加载 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<>)));
}