2013-04-16 2 views
5

У меня есть общий интерфейс IRepository<T> и две реализации xrmRepository<T> и efRepository<T>Ninject контекстная Связывание ж/Open Дженерики

Я хочу, чтобы изменить связывание на основе T, более конкретно использовать xrmRepository когда T происходит от Entity. Как я могу это сделать?

я в настоящее время:

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(); 

Но когда я пытаюсь решить IRepository<Contact> он идет efRepository, хотя Контакт наследует Entity.

Я не хочу использовать Named Bindings, иначе мне придется добавлять имена повсюду.

ответ

2

Вы также можете определить такие привязки. Я не знаю о производительности во время выполнения, но я думаю, что это более читаемо. И если я не пропущу что-то, это должно привести к такому же поведению.

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

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

Редактировать

Если цель состоит в том, чтобы использовать xrmRepository для каждого класса наследуемых от лица этого следует сделать трюк

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

Не работает, используя базовый класс «Сущность». Все еще привязка к efRepository. Работает, если используется сам класс (например, Contact). –

+0

Вы хотите разрешить IRepository для xrmRepository для всех подклассов Entity? – treze

+0

Да! Но я, вероятно, в конечном итоге создам IXRMRepository: IRepository, потому что я не могу заставить его работать. –

1

Используйте метод When, чтобы объявить условие привязки. Пример приведен ниже

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> 
+0

Keep получать сообщение об ошибке «GenericArguments [0],«sf2015 .Infrastructure.Xrm.Contact ', on' sf2015.Repositories.sfRepository'1 [T] 'нарушает ограничение параметра типа' T '. ". Дополнительная информация: f2015.Infrastructure.Xrm.Contact имеет тип Microsoft.Xrm.Sdk.Entity. Мне пришлось изменить First() на [0], и xrmRepository - это тот, который должен связываться с Entity. См. Обновленный вопрос. –

+0

@JoaoLeme дает определения интерфейсов и их реализацию. Также дайте примеры вызова ** Get ** и ожидаемых результатов –

+0

При вызове Get из нового модуля он работает, если я использую ... GetGenericArguments(). First() == typeof (Contact) ... и вызывает kernel.Get >(); но если я заменил Contact на привязку своим унаследованным классом Entity и вызвал kernel.Get >() Я получаю ту же ошибку. Кстати, выполнение такого же трюка с устранением неполадок (замена Entity by Contact) в разделе RegisterServices в NinjectWebCommon не работает (также дает мне ту же ошибку). –

Смежные вопросы