2

是否可以在不指定實施類型的情況下使用RegisterConditional(類似於Register的工作方式,但是有條件)?在條件下注冊開放式仿製藥

我正在使用Simple Injector爲我的CQRS/MVC應用程序進行流暢的驗證。到現在爲止,登記驗證(即都使用MVC和由CQRS堆棧裝飾管)一直簡單:

container.Register(typeof(IValidator<>), assemblies, lifestyle); 

container.RegisterConditional(
    typeof(IValidator<>), 
    typeof(ValidateNothingDecorator<>), 
    Lifestyle.Singleton, 
    c => !c.Handled) 

新的要求意味着我需要實現類似於valiators的東西,但提供警告。我不想使用Fluent驗證的內置「錯誤級別」出於各種原因,這意味着我需要爲給定的類型創建額外的驗證程序,當然會爲單一類型的驗證錯誤提供多個註冊。

我想什麼做的是註冊任何實現IValidator<>除如果它也實現了IProvideWarnings,但我不想列出每類註冊

public class MyCommand : IDefineCommand {...} 
public class ValidateMyCommand : IValidator<MyCommand> {...} 
public class ProvideWarningsForMyCommand : IValidator<MyCommand>, IProvideWarnings {...} 
... 
// would like something like... (this obviously does not work) 
container.RegisterConditional(
    typeof(IValidator<>), 
    assemblies, 
    lifestyle, 
    c => !c.ImplementationType.GetInterfaces().Contains(typeof(IProvideWarnings))); 

我的退路是要找到所有類型實現IValidator<>但不是IProvideWarnings並將其傳遞到Register,但是,我寧願在註冊調用中使用謂詞而不是其他查找。

謝謝

回答

1

正如你已經注意到了,簡單的噴油器包含Register超載允許提供一個類型列表進行註冊。雖然您可以自己反思裝配,但簡單注射器包含便於您使用的方法GetTypesToRegister。這個GetTypesToRegister會自動爲您過濾裝飾器和泛型類型定義。

下面的註冊就可以了:

var validatorTypes = 
    container.GetTypesToRegister(typeof(IValidator<>)) 
     .Where(typeof(IProvideWarnings).IsAssignableFrom); 

container.Register(typeof(IValidator<>), validatorTypes, lifestyle); 
+0

謝謝,這比我的代碼更加整潔,而且我沒有意識到(或者至少沒有深入到足以認識到使用)'GetTypesToRegister'。我會用這個! – AndrewP

1

我解決這個問題的方法是使用我的備用位置。

銘記有下面的代碼非標準方法(但應該是直的前鋒就夠了),它看起來像:

var validatorTypes = assemblies.SelectMany(a => a.GetTypes().Where(t => 
      t.IsClass && !t.IsAbstract && t.IsPublic && 
      t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IValidator<>)) && 
      !t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IProvideWarnings<>)) 
     )).ToList(); 

IocContainer.Register(typeof(IValidator<>), validatorTypes, IocContainer.DefaultLifestyle); 

IocContainer.RegisterConditional(typeof(IValidator<>), typeof(ValidateNothingDecorator<>), Lifestyle.Singleton, c => !c.Handled && !c.ServiceType.DoesImplement(typeof(IProvideWarnings))); 
+0

你ValidateNothingDecorator其實不是裝飾,而是一個空對象。 – Steven