Search code examples
c#asp.netninject

C# Ninject binding from Dictionary<Type, Type>


I'm using Ninject lib in my project. I have a task: I need to bind interfaces to services by passed Dictionary<Type, Type>, I prefer to use reflection.

Without reflection this is done so:

kernel.Bind<IUser>().To<User>();

Where IUser - interface, User - IUser implementation.

In reflection I'm doing so:

MethodInfo method = kernel.GetType().GetMethods().FirstOrDefault(x=>x.Name == "Bind");
MethodInfo genericBind = method.MakeGenericMethod(bind.Key);
MethodInfo bindResult = genericBind.Invoke(kernel,null).GetType().GetMethods().FirstOrDefault(x => x.Name == "To" && x.IsGenericMethod == true);
MethodInfo genericTo = bindResult.MakeGenericMethod(bind.Value);
genericTo.Invoke(kernel, null); //Error is here

but I get an error System.Reflection.TargetException.

What is wrong?


Solution

  • Ok your issue is that you are invoking the method on the kernel object and not on the result of the method. This will fix your problem

    MethodInfo method = kernel.GetType().GetMethods().FirstOrDefault(x=>x.Name == "Bind");
    MethodInfo genericBind = method.MakeGenericMethod(bind.Key);
    var result = genericBind.Invoke(kernel,null);
    MethodInfo bindResult = result.GetType().GetMethods().FirstOrDefault(x => x.Name == "To" && x.IsGenericMethod == true);
    MethodInfo genericTo = bindResult.MakeGenericMethod(bind.Value);
    genericTo.Invoke(result, null); //Error is here
    

    BUT all of this is unnecessary since the Bind function has a non generic implementation kernel.Bind(typeof(IUser)).To(typeof(User)) so you can just do kernel.Bind(bind.Key).To(bind.Value)