C# 如何使用Ninject将参数构造函数注入存储库构造函数?

C# 如何使用Ninject将参数构造函数注入存储库构造函数?,c#,asp.net-web-api,model-view-controller,ninject,repository-pattern,C#,Asp.net Web Api,Model View Controller,Ninject,Repository Pattern,我试图通过在运行时传递连接字符串来创建DBContect对象。 下面是我的NiNject存储库实现的结构 public class HomeController : ApiController { MyService _service{ get; set; } public HomeController(MyService service) { _service= service; } } public class MyService {

我试图通过在运行时传递连接字符串来创建DBContect对象。 下面是我的NiNject存储库实现的结构

public class HomeController : ApiController
{
    MyService _service{ get; set; }

    public HomeController(MyService service)
    {
        _service= service;
    }
}

public class MyService 
{
    IRepository _repo { get; set; }

    public MyService(IRepository repo)
    {
        _repo = repo;
    }
}
存储库的实现如下所示:

public interface IRepository
{
    TenantDbContext _db { get; set; }
    void Add<T>(T entity) where T : class;
    void Delete<T>(int id) where T : class;
    T Find<T>(int id) where T : class;
    IQueryable<T> Query<T>() where T : class;
    void SaveChanges();

    MasterDbContext _db_master { get; set; }
    void Add_Master<T>(T entity) where T : class;
    void Delete_Master<T>(int id) where T : class;
    T Find_Master<T>(int id) where T : class;
    IQueryable<T> Query_Master<T>() where T : class;
    void SaveChanges_Master();
}

public class Repository : IRepository
{
    public TenantDbContext _db { get; set; }
    public MasterDbContext _db_master { get; set; }

    public Repository(TenantDbContext db)
    {
        _db = db;
    }
    public Repository(MasterDbContext db_master)
    {
        _db_master = db_master;
    }
    public IQueryable<T> Query<T>() where T : class
    {
        return _db.Set<T>().AsQueryable();
    }
    public IQueryable<T> Query_Master<T>() where T : class
    {
        return _db_master.Set<T>().AsQueryable();
    }
//.....Rest of the implemetation
}
公共接口IRepository
{
TenantDbContext_db{get;set;}
无效添加(T实体),其中T:类别;
void Delete(int id),其中T:class;
T Find(int-id),其中T:class;
IQueryable Query(),其中T:class;
void SaveChanges();
MasterDbContext_db_master{get;set;}
void Add_Master(T实体),其中T:类;
void Delete_Master(int id),其中T:class;
T查找_Master(int id),其中T:class;
IQueryable Query_Master(),其中T:class;
void SaveChanges_Master();
}
公共类存储库:IRepository
{
公共租户上下文_db{get;set;}
公共MasterDbContext_db_master{get;set;}
公共存储库(TenantDbContext数据库)
{
_db=db;
}
公共存储库(MasterDbContext db_master)
{
_db_master=db_master;
}
公共IQueryable查询(),其中T:class
{
返回_db.Set().AsQueryable();
}
公共IQueryable查询\u Master(),其中T:class
{
返回_db_master.Set().AsQueryable();
}
//……其余的默示
}
下面是我的TenantDBContext类,它将一个参数作为数据库字符串无默认构造函数

 public class TenantDbContext : DbContext
{
    public TenantDbContext(string connString)
        : base(connString)
    {
        //Configuration.AutoDetectChangesEnabled = true;
        //Configuration.LazyLoadingEnabled = false;
        //Configuration.ProxyCreationEnabled = false; //change tracking 
    }

    public static TenantDbContext Create(string DbString)
    {
        // Some logic to get the tenant database string. 
        // Presently i am just passing it hard coded as follows.

        return new TenantDbContext(DbString);
    }
}
public class MasterDbContext : IdentityDbContext<ApplicationUser>
{
    public MasterDbContext() : base("MasterDBConnection", throwIfV1Schema: false)
    {
       // dbmigration.AutomaticMigrationsEnabled = true;
        Configuration.ProxyCreationEnabled = false;
        Configuration.LazyLoadingEnabled = false;
    }
    public static MasterDbContext Create()
    {
        return new MasterDbContext();
    }

    //public DbSet<ApplicationUser> ApplicationUsers { get; set; }
    public DbSet<Tenant> Tenants { get; set; }
    public DbSet<TenantUserMap> TenantUserMaps { get; set; } }
public类TenantDbContext:DbContext
{
public TenantDbContext(字符串connString)
:base(字符串)
{
//Configuration.AutoDetectChangesEnabled=true;
//Configuration.LazyLoadingEnabled=false;
//Configuration.ProxyCreationEnabled=false;//更改跟踪
}
publicstatictenantdbContext创建(stringdbstring)
{
//获取租户数据库字符串的一些逻辑。
//目前,我只是通过它硬编码如下。
返回新的TenantDbContext(DbString);
}
}
公共类MasterDbContext:IdentityDbContext
{
public MasterDbContext():base(“MasterDBConnection”,throwifvv1schema:false)
{
//dbmigration.AutomaticMigrationsEnabled=true;
Configuration.ProxyCreationEnabled=false;
Configuration.LazyLoadingEnabled=false;
}
公共静态MasterDbContext Create()
{
返回新的MasterDbContext();
}
//公共数据库集应用程序用户{get;set;}
公共数据库集租户{get;set;}
公共数据库集租户映射{get;set;}
最后,我在NinjectWebCommons.cs中的RegisterServices如下所示: 每个租户都有其不同的数据库。我们从每个请求的访问令牌中提取租户名称,并缓存请求的租户对象,以便传递正确的租户数据库字符串,以便对请求的租户数据库执行操作

在下面的代码片段中,我们从当前请求缓存中获取租户对象,该缓存将为我们提供请求客户端的租户数据库字符串

 public Tenant Tenant
    {
        get
        {
            object multiTenant;
            if (!HttpContext.Current.GetOwinContext().Environment.TryGetValue("MultiTenant", out multiTenant))
            {
                throw new ApplicationException("Could Not Find Tenant");
            }
            return (Tenant)multiTenant;
        }
    }

private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IRepository>().To<Repository>();
        kernel.Bind<TenantDbContext>().ToMethod(_ => 
        TenantDbContext.Create(Tenant.DBString)); 
        kernel.Bind<MasterDbContext>().ToMethod(__ => MasterDbContext.Create());
    }   
公共租户
{
得到
{
客体多租户;
if(!HttpContext.Current.GetOwinContext().Environment.TryGetValue(“多租户”,out多租户))
{
抛出新的ApplicationException(“找不到租户”);
}
归还(承租人)多租户;
}
}
私有静态无效注册服务(IKernel内核)
{
kernel.Bind().To();
kernel.Bind()
Create(Tenant.DBString));
kernel.Bind();
}   
问题:当我在我的NinjectWebCommons.cs“kernel.Bind()”中添加第二个绑定时,我开始得到异常,说“找不到默认构造函数”。它只是不接受内核的两个绑定。请你看看上面的代码,并指出我哪里出了问题


我将感谢你的帮助。提前感谢。

您可以为数据库上下文添加绑定,并指向Ninject以使用出厂方法:

kernel.Bind<TenantDbContext>().ToMethod(_ => TenantDbContext.Create());
kernel.Bind().ToMethod(=>TenantDbContext.Create());

您可以为数据库上下文添加绑定,并指向Ninject以使用出厂方法:

kernel.Bind<TenantDbContext>().ToMethod(_ => TenantDbContext.Create());
kernel.Bind().ToMethod(=>TenantDbContext.Create());

您需要告诉容器如何构建
DbContext
。我不使用Ninject,但其逻辑类似于
内核。[在查找TenantDbContext时].[将此构造函数与此connString一起使用]
查看感谢Jonesopolis的及时回复。我尝试按照您的建议执行以下操作:
kernel.Bind().to().WithConstructorArgument(“connString”,“数据源=something;初始目录=something;uid=something;pwd=something”)
我知道它错了,只是想检查它是否运行。令人惊讶的是,它开始执行,但连接字符串没有形成。您需要告诉容器如何构建
DbContext
。我不使用Ninject,但其逻辑类似于
内核。[在查找TenantDbContext时].[将此构造函数与此connString一起使用]
查看感谢Jonesopolis的及时回复。我尝试按照您的建议执行以下操作:
kernel.Bind().to().WithConstructorArgument(“connString”,“数据源=something;初始目录=something;uid=something;pwd=something”)
我知道它错了,只是想检查它是否运行。令人惊讶的是,它开始执行,但连接字符串没有形成。非常感谢它,它就像一个老板一样工作。你们的概念很清楚。:)嗨,佩伊特,我正在尝试添加另一个ToMethod,但是NInject没有给出默认构造函数错误,因此停止了工作<代码>kernel.Bind().ToMethod(=>TenantDbContext.Create())
kernel.Bind().ToMethod(\ux=>