2011-06-02 38 views
6

我有一個抽象類:Ninject:針對通用類默認與特定的綁定

public abstract class Validator<T> : IValidator 

和一對夫婦的實現這個類用於特定目的的課程,例如

public sealed class NewsValidator : Validator<News> 

現在使用Ninject我想要做的依賴注入如下內容(這個特殊的代碼是不工作):

Bind<Validator<News>>().To<NewsValidator>(); 
Bind(typeof(Validator<>)).To(typeof(NullValidator<>)); 

所以我想實現的是

Validator<News> 

應該綁定到「NewsValidator」類,但是如果請求了此類的其他任何未綁定版本,請說

Validator<Article> 
Validator<SomethingElse> 

應該綁定到默認的類(NullValidator)。不過,使用上面使用的代碼會拋出一個Exception,因爲它將驗證程序News>既綁定到NewsValidator上,也綁定到NullValidator上。

我該如何實現?泛型類的特定類型應該綁定到單獨的類。所有其他類型的未明確綁定的泛型類都應綁定到默認類。

對於一些建議真的很高興!謝謝!

回答

9

您可以創建一個IMissingBindingResolver的自定義實現。

每當內核未能解析所請求服務的綁定時,它將委託給HandleMissingBinding方法(對於從​​派生的任何內核都是如此)。 HandleMissingBinding方法將詢問每個缺少的綁定解析器是否可以爲請求的服務創建一個綁定。解析器返回的綁定(如果有的話)將被添加到內核中。

請注意,由缺少的綁定解析器創建的任何綁定都將作爲隱式綁定添加到內核中。這可能會影響您的應用程序。例如,如果您有一個服務的顯式和隱式綁定混合,解析這些綁定(即kernel.GetAll<TService>())只能解析顯式綁定。但是,如果所有綁定都是隱含的,它們都將被解析。

Ninject有IMissingBindingResolver的兩個標準實現:

讓我們實現了零驗證自定義解析。

public class MissingValidatorResolver : NinjectComponent, IMissingBindingResolver 
{ 
    public IEnumerable<IBinding> Resolve(
     Multimap<Type, IBinding> bindings, IRequest request) 
    { 
     var service = request.Service; 
     if (!typeof(IValidator).IsAssignableFrom(service)) 
     { 
      return Enumerable.Empty<IBinding>(); 
     } 

     var type = service.GetGenericArguments()[0]; 
     var validatorType = typeof(NullValidator<>).MakeGenericType(type); 

     var binding = new Binding(service) 
     { 
      ProviderCallback = StandardProvider.GetCreationCallback(validatorType) 
     }; 

     return new[] { binding }; 
    } 
} 

現在下面的測試(使用xUnit.net)通過。

[Fact] 
public void ShouldResolveNonBoundValidatorDerivedFromValidatorAsNullValidator() 
{ 
    var kernel = new StandardKernel(); 
    kernel.Components.Add<IMissingBindingResolver, MissingValidatorResolver>(); 

    var validator = kernel.Get<Validator<Article>>(); 
    Assert.IsType<NullValidator<Article>>(validator); 
} 
+0

whoa :)不可思議,那個人的工作就像一個魅力。你怎麼知道的?!即使谷歌搜索「IMissingBindingResolver」時也找不到很多東西。無論如何,這絕對是完美的,非常感謝! – Oliver 2011-06-03 00:26:15