C# 带开放泛型的Ninject上下文绑定

C# 带开放泛型的Ninject上下文绑定,c#,generics,repository,dynamics-crm-2011,ninject,C#,Generics,Repository,Dynamics Crm 2011,Ninject,我有一个通用接口IRepository和两个实现xrmRepository和eRepository 我想更改基于T的绑定,更具体地说,当T派生自实体时,使用xrmrrepository。我怎样才能做到这一点 我目前有: kernel.Bind(typeof(IRepository<>)).To(typeof(efRepository<>)).InRequestScope(); kernel.Bind(typeof(IRepository<>)).To(type

我有一个通用接口
IRepository
和两个实现
xrmRepository
eRepository

我想更改基于
T
的绑定,更具体地说,当
T
派生自
实体时,使用
xrmrrepository
。我怎样才能做到这一点

我目前有:

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();
kernel.Bind(typeof(IRepository)).To(typeof(efRepository)).InRequestScope();
kernel.Bind(typeof(IRepository)).To(typeof(xrmrrepository)).When(request=>request.Service.GetGenericArguments()[0]。GetType().IsSubclassOf(typeof(Entity))).InRequestScope();
但当我尝试解析
IRepository
时,它会转到eRepository,即使Contact继承了实体


我不想使用命名绑定,否则我将不得不到处添加名称。

使用
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>
kernel.Bind(typeof(IRepository))
.至(类型(电子存储))
.When(request=>request.Service.GetGenericArguments()[0]==typeof(Entity))
.InRequestScope();
kernel.Bind(typeof(IRepository))
.To(类型(XRM存储库))
.InRequestScope();
Get()//将返回eRepository
Get()//将返回XRM存储库

您也可以这样定义绑定。我不知道运行时性能如何,但我认为这样更可读。如果我没有遗漏什么,那么我也会有同样的行为

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

kernel.Bind<IRepository<Entity>>()
      .To<xrmRepository<Entity>>()
      .InRequestScope();
kernel.Bind(typeof(IRepository))
.至(类型(电子存储))
.InRequestScope();
kernel.Bind()
.至()
.InRequestScope();
编辑

如果目标是对从实体继承的每个类使用xrmRepository,那么这应该可以做到

kernel.Bind(typeof(IRepository<>))
                    .To(typeof(XrmRepository<>))
                    .When(request => typeof(Entity).IsAssignableFrom(request.Service.GetGenericArguments()[0]));
kernel.Bind(typeof(IRepository))
.To(类型(XRM存储库))
.When(request=>typeof(Entity).IsAssignableFrom(request.Service.GetGenericArguments()[0]);

在“sf2015.Repositories.sfRepository`1[T]”上不断出现错误“GenericArguments[0],“sf2015.Infrastructure.Xrm.Contact”,违反了类型参数“T”的约束。传统信息:f2015.Infrastructure.Xrm.Contact的类型为Microsoft.Xrm.Sdk.Entity。我必须将First()更改为[0],并且xrmRepository应该与实体绑定。请参阅更新的问题。@JoaoLeme给出接口定义及其实现。同时给出调用Get和预期结果的示例当从新模块调用Get时,如果我使用…GetGenericArguments().First()==typeof(Contact)…,它会工作。。。并调用kernel.Get();但是如果我用继承的类实体替换绑定上的Contact并调用kernel.Get(),我会得到相同的错误。顺便说一句,在NinjectWebCommon中的RegisterServices下执行相同的故障排除技巧(以联系人替换实体)不起作用(Eitherway会给出相同的错误)。使用基类“Entity”不起作用。仍然绑定到eForepository。如果使用类本身(如Contact),则有效。是否要为实体的所有子类将IRepository解析为XRMRRepository?是的!但我可能会创建一个IXRMRepository:IRepository,因为我无法让它工作。是的,它应该适用于可以分配给实体的所有类型