2015-10-21 21 views
1

我正在使用Ninject v2.2.1.4,所以我不確定這是新版本的ninject如何工作。通用接口的多個綁定錯誤

我打算使用一個經典的繼承例子Animal。所以我有一個基礎摘要Animal類,然後有Animal的無數實現。

public abstract class Animal { } 
public class Tiger : Animal { } 

現在我有一個AnimalIValidator,使確保屬性設置正確。

public interface IValidator<T> 
{ 
    bool Validate(T object); 
} 

對於Animal每個實現(虎,貓,狗等。)我可能會或可能不會有一個IValidator<T>實現。如果沒有針對特定動物的驗證程序,我想使用驗證基礎Animal屬性(IValidator<Animal>)的默認驗證程序。

所以這裏是IValidator<T>一對夫婦的實現,包括默認的實現:

// Contains default logic for base Animal inherited by all validators 
public abstract class AbstractAnimalValidator<TAnimal> : IValidator<TAnimal> where TAnimal : Animal { } 
// Default implementation for IValidator when the animal doesn't have a validator. 
//This just calls the base abstract validator logic. 
public DefaultAnimalValidator : AbstractAnimalValidator<Animal> { } 
// Validator for a Tiger. It calls the base validate method and then validates properties specific to a Tiger. 
public TigerValidator : AbstractAnimalValidator<Tiger> { } 

讓我們姑且認爲老虎是與它自己的驗證的唯一動物。我想有這兩個綁定:

Bind<IValidator<Animal>>().To<DefaultAnimalValidator>(); 
Bind<IValidator<Tiger>>().To<TigerValidator>(); 

所以現在我會試圖注入的具體的動物驗證,通過嘗試得到實現,如注射IValidator<Tiger>邏輯。如果不存在,則使用IValidator<Animal>注入默認驗證器。

問題是,當試圖注入IValidator<Tiger>,上述兩個綁定匹配,所以我得到一個多綁定發現錯誤。這是因爲Tiger繼承自Animal,所以Tiger既是Tiger也是Animal。我已經想出了一些解決方法,但是有什麼我失蹤了?

回答

1

您可以修改IValidator<T>界面嗎?如果是的話,你可以標記類型參數爲逆變:

public interface IValidator<in T> 
{ 
    bool Validate(T o); 
} 

它可以讓你分配一個IValidator<Animal>IValidator<Tiger>。然後,你可以明確地指定所有綁定:

Bind<IValidator<Cat>>().To<DefaultAnimalValidator>(); 
Bind<IValidator<Dog>>().To<DefaultAnimalValidator>(); 
Bind<IValidator<Tiger>>().To<TigerValidator>(); 

這種方法有一個還隱含了回退到IValidator<Animal>很大的優勢。如果您添加另一個從Animal派生的類,並且它自己的驗證器忘記添加綁定,則會出現運行時錯誤。如果你使用Bind<IValidator<Animal>>().To<DefaultAnimalValidator>(),你將很難追查錯誤。

+0

不幸的是,我無法修改界面。我正在使用FluentValidation庫。另外,這是一個非常簡單的例子。我們沒有明確地設置這樣的綁定。我們正在使用一個綁定生成器,並不真正想要修改綁定生成器中的邏輯。我希望有一個更好的方式來構建這個,以便我可以獲得預期的功能。 –

+0

@wired_in [Ninject contextual-binding](https://github.com/ninject/Ninject/wiki/Contextual-Binding)可能有幫助嗎? –