簡體   English   中英

在Ninject中尋找通用接口的具體實現

[英]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);

當然,缺點是您會失去編譯時支持,但如果這兩行代碼是應用程序中唯一一個像這樣調用獸醫的行,我會說沒問題。 您可以輕松添加檢查此代碼的單元測試。

請注意,即使你在DogGoldenRetriever上都有vet實現,並希望能夠將一個GoldenRetriever應用於Vet<Dog> ,那么Vet<in T>中的in關鍵字可能是無用的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM