2017-08-14 47 views
2

我想以未來證明的方式編寫我的組合根,以便當我添加更多用SimpleInjector 4實現基本實體的命令時,它們會自動獲取。批處理註冊開放式通用實現

域類是這樣的:

public interface ICommandHandler<TCommand> { . . . } 

public class UpdateCommandHandler<T> : ICommandHandler<UpdateCommand<T>> 
    where T : EntityBase { . . . } 

public class UpdateCommand<T> where T : EntityBase { . . . } 

public abstract class EntityBase { . . . } 

我的API控制器,然後使用命令處理程序如下:

// With base entity 
private ICommandHandler<UpdateCommand<BlogEntry>> updateBlogEntryCommandHandler; 
// Without base entity 
private ICommandHandler<AddBlogEntryCommentCommand> addBlogEntryCommentCommandHandler; 

而且我的作文根是這樣的:

// This works for all cases without as base entity e.g: 
// private ICommandHandler<AddBlogEntryCommentCommand> addBlogEntryCommentCommandHandler; 
container.Register(typeof(ICommandHandler<>), new[] { typeof(ICommandHandler<>).Assembly }); 


// And this works for when commands have a base entity but how do to I write it in a 
// generic, future-proof way like above? 

container.Register<ICommandHandler<DeleteCommand<BlogEntryComment>>, DeleteCommandHandler<BlogEntryComment>>(); 
container.Register<ICommandHandler<UpdateCommand<BlogEntry>>, UpdateCommandHandler<BlogEntry>>(); 
container.Register<ICommandHandler<UpdateCommand<BlogEntryFile>>, UpdateCommandHandler<BlogEntryFile>>(); 

注:這與Simple Injector usage for generic command handler類似,但它不回答我的問題。

回答

1

而不是讓所有註冊的封閉仿製版本的開放式通用實現的一個接一個的,你可以將其與自己的開放式泛型類型,而不是註冊:

container.Register(typeof(ICommandHandler<>), typeof(DeleteCommandHandler<>)); 
container.Register(typeof(ICommandHandler<>), typeof(UpdateCommandHandler<>)); 

簡單的噴油器會自動關閉這些類型爲你。只有在添加新的泛型實現時,您必須將其添加爲註冊以使用「組合根」。

如果您希望添加許多泛型類型,則可以改爲在一次使用下面的代碼註冊的所有實現:

var types = container.GetTypesToRegister(typeof(ICommandHandler<>), 
    new[] { typeof(ICommandHandler<>).Assembly }, 
    new TypesToRegisterOptions { IncludeGenericTypeDefinitions = true }); 

container.Register(typeof(ICommandHandler<>), 
    types.Where(t => !t.IsGenericTypeDefinition)); 

foreach (Type type in types.Where(t => t.IsGenericTypeDefinition)) 
{ 
    container.Register(typeof(ICommandHandler<>), type); 
} 

由於限制Register在V4.0(也就是在V4 planned to get fixed。 1),Register(Type, IEnumerable<Type>)不允許將開放泛型類型傳遞給類型列表。這就是爲什麼你必須單獨註冊泛型(現在)。

+0

第一個代碼片段工作正常,但第二個沒有。 'GetTypesToRegister'需要第二個參數的IEnumerable程序集。所以我試着'var types = container.GetTypesToRegister(typeof(ICommandHandler <>),new [] {typeof(ICommandHandler <>)。Assembly},new TypesToRegisterOptions {IncludeGenericTypeDefinitions = true});'但是會拋出以下錯誤:提供的類型列表包含一個或多個開放泛型類型,但是此方法無法處理開放泛型類型,因爲它只能將封閉泛型服務類型映射到單個實現。「# – CatsPajamas

+0

@CatsPajamas:Appologies。更新 – Steven

+1

感謝一百萬人的完美工作。我正在關注Github repo上的開放問題,以便在修復代碼時更新代碼。乾杯! – CatsPajamas