如何使用Ninject将参数构造函数注入到Repository构造函数中?

时间:2017-10-16 12:26:35

标签: c# asp.net-web-api model-view-controller ninject repository-pattern

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

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
}

这是我的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; } }

最后,我在NinjectWebCommons.cs中的RegisterServices如下所示: 每个租户都有不同的数据库。我们在每个请求中从访问令牌中取出租户名称并缓存请求的租户对象,以便我们可以传递正确的租户数据库字符串,以便对请求的租户数据库执行操作。

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

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

问题:当我在NinjectWebCommons.cs“kernel.Bind()”中添加第二个绑定时,我开始得到异常,说“找不到默认构造函数”。它根本没有与核心进行两次绑定。请您查看上面的代码,并指出我出错的地方。

感谢您的帮助。在此先感谢。

1 个答案:

答案 0 :(得分:0)

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

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