我在我最近的項目中使用CQRS
模式和使用Structuremap 3
作爲我IoC Container
,所以我定義下面的轉換來解決ICommandHandlers
每個BaseEntity
類型:覆蓋定製登記約定3
public class InsertCommandRegistrationConvention
: StructureMap.Graph.IRegistrationConvention
{
private static readonly Type _openHandlerInterfaceType = typeof(ICommandHandler<>);
private static readonly Type _openInsertCommandType = typeof(InsertCommandParameter<>);
private static readonly Type _openInsertCommandHandlerType = typeof(InsertCommandHandler<>);
public void Process(Type type, Registry registry)
{
if (!type.IsAbstract && typeof(BaseEntity).IsAssignableFrom(type) &&
type.GetInterfaces().Any(x => x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(IAggregateRoot<>)))
{
Type closedInsertCommandType = _openInsertCommandType.MakeGenericType(type);
Type closedInsertCommandHandlerType =
_openInsertCommandHandlerType.MakeGenericType(type);
Type insertclosedHandlerInterfaceType =
_openHandlerInterfaceType.MakeGenericType(closedInsertCommandType);
registry.For(insertclosedHandlerInterfaceType)
.Use(closedInsertCommandHandlerType);
}
}
}
,並用它在我CompositionRoot:
public static class ApplicationConfiguration
{
public static IContainer Initialize()
{
ObjectFactory.Initialize(x =>
{
x.Scan(s =>
{
s.TheCallingAssembly();
s.WithDefaultConventions();
s.Convention<InsertCommandRegistrationConvention>();
});
});
return ObjectFactory.Container;
}
}
所以我的每一個實體,它例如註冊適當InsertCommandHandler
其註冊
的InsertCommandHandler<InsertCommandParameter<Order>>
爲ICommandHandler<ICommandParameter<Order>>
有時我需要爲某些實體,例如用於Product
我要註冊非通用InsertProductCustomCommandHandler
類ICommandHandler<ICommandParameter<Product>>
代替InsertCommandHandler<InsertCommandParameter<Product>>
(在其他的字註冊自定義InsertCommandHandler
S,我想覆蓋InsertCommendRegistrationConvention
)。
我怎麼能這樣做,結構圖3?
我用過容器。Configure()',但是當我運行'WhatDoIHave()'時,它顯示'ICommandHandler>'結構映射同時使用'InsertCommandHandler '作爲默認值和自定義'InsertCalendarCommandHandler'(但不是默認值)。 –
Masoud
Hi @Masoud - 我的代碼向他們展示了另一個有點令人費解的方式 - 在調用ApplicationConfiguration.Initialize()後添加了自定義註冊嗎? – qujck
你說得對,在修復它之後,我使用'container.Configure()'代替'container.Initialize()'來代替通用的'InsertCommandHandlers',現在'InsertCalendarCommandHandler'是默認的,'ICommandHandler>'不是。但我的程序是模塊化的,我不能每個模塊都有一個'Initialize()'。所以我必須爲程序設置一個「初始化」,爲每個模塊設置一個「配置」。 –
Masoud