![](/img/trans.png)
[英]Ninject binding generic interface to generic concrete class with multiple parameters
[英]Finding a Concrete Implementation of a Generic Interface in Ninject
我有一個具有特定實現的通用接口,如下所示:
public class Animal { }
public class Horse : Animal { }
public class Dog : Animal { }
public interface Vet<in T> where T : Animal
{
void Heal(T animal);
}
public class HorseVet : Vet<Horse>
{
public void Heal(Horse animal)
{
Console.WriteLine("Healing a horse");
}
}
public class DogVet : Vet<Dog>
{
public void Heal(Dog animal)
{
Console.WriteLine("Healing a dog");
}
}
現在我希望能夠在運行時給定Animal
創建Vet<T>
的適當具體實現的實例,如下所示:
StandardKernel kernel = new StandardKernel();
kernel.Bind<Vet<Horse>>().To<HorseVet>();
kernel.Bind<Vet<Dog>>().To<DogVet>();
var animals = new Animal[] { new Horse(), new Dog() };
foreach (Animal animal in animals)
{
// how do I get the right Vet<T> type here so I can call Heal(animal)?
}
我的問題是,如何實現上述目標以便檢索正確的實現,或者我是否需要重構以不同的方式組織我的類?
我看過Ninject Factory Extension,但似乎也沒有提供我正在尋找的東西。
如果我沒有使用IoC容器,我會做類似的事情:
public Vet<Animal> Create(Animal animal)
{
if (animal is Horse)
{
return new HorseVet();
}
else if ...
}
foreach (Animal animal in animals)
{
Type vetType = typeof(Vet<>).MakeGenericType(animal.GetType());
object vet = kernel.Get(vetType);
}
但現在的問題是你想如何使用這種類型? 你可能想做這樣的事情:
var vet = (Vet<Animal>)kernel.Get(vetType);
vet.Heal(animal);
但這不起作用,因為Vet<Dog>
和Vet<Horse>
實例無法轉換為Vet<Animal>
,因為這需要使用out
關鍵字定義Vet<T>
,如Vet<out Animal>
。 但這當然行不通,因為Vet<T>
有一個類型為Animal
的輸入參數。
因此,要解決此問題,您需要第二個非通用Vet
接口,或者您需要使用反射或動態類型。 使用非通用接口可能如下所示:
public interface Vet {
void Heal(Animal animal);
}
public interface Vet<T> : Vet where T : Animal {
void Heal(T animal);
}
// Usage
var vet = (Vet)kernel.Get(vetType);
vet.Heal(animal);
然而問題是這會污染實現,因為它們突然需要實現第二種方法。
另一種選擇是使用動態類型或反射:
dynamic vet = kernel.Get(vetType);
vet.Heal((dynamic)animal);
當然,缺點是您會失去編譯時支持,但如果這兩行代碼是應用程序中唯一一個像這樣調用獸醫的行,我會說沒問題。 您可以輕松添加檢查此代碼的單元測試。
請注意,即使你在Dog
和GoldenRetriever
上都有vet實現,並希望能夠將一個GoldenRetriever
應用於Vet<Dog>
,那么Vet<in T>
中的in
關鍵字可能是無用的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.