jeudi 30 mai 2019

Casting classes in generic methods in MEF

I have some classes and interface:

interface IAnimal
{

}

class Cat : IAnimal, ILiveInZoo
{

}
interface ILiveInZoo
{

}

Also, I have some methods and generic methods:

class Context
{
    public ILiveInZoo GetWhoLivesInZoo(string name)
    {
        if (name == "Cat")
            return new Cat();
        return null;
    }
    static CompositionContainer Container = null;
    public void GiveFood<T>(T animal) where T : IAnimal
    {
        var methods = Container.GetExports<Action<T, EventArgs>, AttributeMetadata>();
        //execute methods
    }
}

And here is a use case:

Context context = new Context();
var cat = context.GetWhoLivesInZoo("Cat");
if (cat is IAnimal animal)
{
   context.GiveFood(animal);
}

As you can see in GiveFood metod I'm using MEF. In use case when I cast cat to IAnimal, in GiveFood method typeof(T) will be IAnimal not Cat. First question is: Instance of cat variable is Cat class. Why when I cast it typeof(T) will be IAnimal. My problem is when I cast cat to IAnimal interface, in GiveFood method, GetExports method returns method related to IAnimal not to Cat class. I found solution to fix that issue, it is using reflection:

Context context = new Context();
var cat = context.GetWhoLivesInZoo("Cat");
if (cat is IAnimal animal)
{
   MethodInfo method = typeof(Context).GetMethod(nameof(Context.GiveFood));
   MethodInfo generic = method.MakeGenericMethod(animal.GetType());
   generic.Invoke(context, new object[] { animal });
}

Now typeof(T) is Cat class and in GiveFood I can get methods related to Cat class. Is there another way (without using reflection) to solve this issue?





Aucun commentaire:

Enregistrer un commentaire