将Autofac中的类型注册链作为选项的扩展方法



我正试图在Autofac中实现一些关于注册多个事物的语法糖,但我被卡住了,我不知道这是否有一些设计模式名称可以搜索一些信息。

我在我的主要项目中有这样的东西:

protected override void Load(ContainerBuilder builder)
{
var busBuilder =
new BusBuilder()
.RegisterHandler<EventOne, DomainEventHandlerAdapter<EventOne>>()
.RegisterHandler<EventTwo, DomainEventHandlerAdapter<EventTwo>>()
.RegisterHandler<EventThree, DomainEventHandlerAdapter<EventThree>>();
builder
.RegisterMicroBus(busBuilder);
builder
.RegisterType<MicroBusDomainEventBus>()
.As<IDomainEventBus>();
}

我想重构它,因为我不希望我的主项目依赖于特定的NuGet包(Enexure Microbus包(。所以我想在我的主要项目中有这样的东西:

protected override void Load(ContainerBuilder builder)
{
builder.RegisterMyMicrobus(eventOptions => {
eventOptions
.RegisterDomainHandler<EventOne>()
.RegisterDomainHandler<EventTwo>()
.RegisterDomainHandler<EventThree>();
});
}

因此,我的主要项目对BusBuilder、DomainEventHandlerAdapter或RegisterMicroBus一无所知,也不依赖于该特定技术(Enexure Microbus(。所有的Autofac注册都将由我的另一个项目处理,这是唯一一个依赖特定技术的项目。

以下是我迄今为止在另一个项目上所做的工作:

我在Autofac的ContainerBuilder上创建了一个扩展方法,我将在其中传递eventOptions,它将是一个委托(lambda表达式(Action<EventOption>

public static void RegisterMyMicrobus(this ContainerBuilder builder, Action<EventOption> eventOptions = null)
{
var busBuilder = new BusBuilder();
if (eventOptions != null)
{
// TODO, how to implement EventOption and the chain registration?
}
builder
.RegisterMicroBus(busBuilder);
builder
.RegisterType<MicroBusDomainEventBus>()
.As<IDomainEventBus>();
}

任何链接或帮助都将不胜感激。这个模式必须有一个名称,但不知道它是如何调用的,而且我没有实现链方法的经验。

更新1:根据Erndob的建议,我查看了BusBuilder。但我又一次陷入了困境。

我创建了EventOption如下:

public class EventOption
{
public IReadOnlyList<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
private readonly List<IDomainEvent> _domainEvents= new List<IDomainEvent>();
public EventOption RegisterDomainHandler(IDomainEvent domainEvent)
{
_domainEvents.Add(domainEvent);
return this;
}
}

但现在问题出在扩展方法上,因为我可以检索事件列表

public static void RegisterMyMicrobus(this ContainerBuilder builder, Action<EventOption> eventOptions = null)
{
var busBuilder = new BusBuilder();
// use busBuilder to register each one of the domain events in options
var eventOption = new EventOption();
eventOptions?.Invoke(eventOption);
foreach (var domainEvent in eventOption.DomainEvents)
{
var eventType = domainEvent.GetType();
// HERE is the problem. How to RegisterHandler using this generic method?
busBuilder
.RegisterHandler<eventType, DomainEventHandlerAdapter<eventType>>();
}
builder
.RegisterMicroBus(busBuilder);
builder
.RegisterType<MicroBusDomainEventBus>()
.As<IDomainEventBus>();
}

它不会编译,因为我试图将变量用作类型(RegisterHandler是泛型(。我找不到将变量转换为满足该调用的类型的方法。有什么想法或不同的方式来实现同样的目标吗?再次感谢

更新2:我已经改变了方法,它似乎可以工作。它编译并注册所有内容,但我必须进一步测试。

我已修改EventOption以存储类型:

public class EventOption
{
public IReadOnlyList<Type> Types => _types.AsReadOnly();
private readonly List<Type> _types = new List<Type>();
public DomainCommandOptions RegisterCommandHandler<TDomainCommand>()
where TDomainCommand : IDomainCommand
{
var domainCommandType = typeof(TDomainCommand);
_types.Add(domainCommandType);
return this;
}
}

然后扩展方法现在不同了,因为它在类型上进行迭代,并在运行时创建一个泛型类型。我发现Microbus有一个HandlerRegistration,我可以直接使用。

public static void RegisterMyMicrobus(this ContainerBuilder builder, Action<EventOption> eventOptions = null)
{
var busBuilder = new BusBuilder();
// use busBuilder to register each one of the domain events in options
var eventOption = new EventOption();
eventOptions?.Invoke(eventOption);
foreach (var type in eventOption.Types)
{
var handlerRegistration = new HandlerRegistration(type, typeof(DomainEventHandlerAdapter<>).MakeGenericType(type));
busBuilder.RegisterMessage(handlerRegistration);
}
builder
.RegisterMicroBus(busBuilder);
builder
.RegisterType<MicroBusDomainEventBus>()
.As<IDomainEventBus>();
}

查看您正在使用的项目的源代码。BusBuilder,这个链接的东西,在它的名字中有一个模式名称。建设者。回购本身说:

MicroBus是的一个简单的进程中中介。净

因此MicroBus是一个中介。看看中介模式。

以下是BusBuilder.cs的外观:https://github.com/Lavinski/Enexure.MicroBus/blob/master/src/Enexure.MicroBus/BusBuilder.cs

建筑本身基本上是这样做的:

public BusBuilder RegisterHandler<TMessage, TMessageHandler>() 
where TMessageHandler : IMessageHandler<TMessage, Unit>
{
registrations.Add(HandlerRegistration.New<TMessage, TMessageHandler>());
return this;
}

正如您所看到的,实例有一个注册列表,然后当您想要注册新的东西时,它只会添加到列表中,然后返回自己,让您可以链接新的注册。

相关内容

  • 没有找到相关文章

最新更新