Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ninject Contextual Binding w/ Open Generics

I have a generic interface IRepository<T> and two implementations xrmRepository<T> and efRepository<T>

I want to change the binding based on T, more specifically use xrmRepository when T derives from Entity. How can I accomplish that?

I currently have:

kernel.Bind(typeof(IRepository<>)).To(typeof(efRepository<>)).InRequestScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(xrmRepository<>)).When(request => request.Service.GetGenericArguments()[0].GetType().IsSubclassOf(typeof(Entity))).InRequestScope();

But when I try to resolve IRepository<Contact> it goes to efRepository, even though Contact inherits Entity.

I don't want to use Named Bindings otherwise I will have to add the names everywhere.

like image 910
Joao Leme Avatar asked Oct 04 '22 09:10

Joao Leme


2 Answers

You can also define the bindings like this. I don't know about run time performance, but I think it's more readable this way. And if I'm not missing something it should result in the same behavior.

kernel.Bind(typeof(IRepository<>))
      .To(typeof(efRepository<>))
      .InRequestScope();

kernel.Bind<IRepository<Entity>>()
      .To<xrmRepository<Entity>>()
      .InRequestScope();

Edit

If the goal is to use xrmRepository for every class inheriting from Entity this should do the trick

kernel.Bind(typeof(IRepository<>))
                    .To(typeof(XrmRepository<>))
                    .When(request => typeof(Entity).IsAssignableFrom(request.Service.GetGenericArguments()[0]));
like image 193
treze Avatar answered Oct 12 '22 06:10

treze


Use When method to declare a binding condition. Example is given below

kernel.Bind(typeof(IRepository<>))
      .To(typeof(efRepository<>))
      .When(request => request.Service.GetGenericArguments()[0] == typeof(Entity))
      .InRequestScope();

kernel.Bind(typeof(IRepository<>))
      .To(typeof(xrmRepository<>))
      .InRequestScope();

kernel.Get<IRepository<Entity>>(); //will return efRepository<Entity>

kernel.Get<IRepository<int>>(); //will return xrmRepository<int>
like image 28
Ilya Ivanov Avatar answered Oct 12 '22 07:10

Ilya Ivanov