1

我想在運行時通過傳遞連接字符串來創建DBContect對象。 以下是我的NiNject存儲庫實現的結構。如何使用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; } } 

最後,RegisterServices我已經在我的NinjectWebCommons.cs如下所示: 每個租戶有其不同的數據庫。我們從每個請求中獲取訪問令牌中的Tenant名稱並緩存請求的Tenant對象,以便我們可以傳遞正確的Tenant數據庫字符串,以便對請求的Tenant數據庫執行操作。

在下面的代碼片段中,我們從當前請求緩存中獲取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()」,我開始變得異常說「沒有默認構造函數找到」。它根本不會與內核綁定。請你請看看上面的代碼,並指出我在哪裏出錯。

我會感謝您的幫助。提前致謝。

+0

你需要告訴你的容器如何建立你的'DbContext'。我不使用Ninject,但是邏輯就像'kernel。[在尋找TenantDbContext時] [用這個connString使用這個構造函數]' – Jonesopolis

+0

看看[這個答案](https://stackoverflow.com/questions/35308511/how-to-make-ninject-choose-a-specific-constructor-without-using-injectattribute) – Jonesopolis

+0

感謝Jonesopolis的及時回覆。我嘗試按照你的建議做如下操作:
'kernel.Bind ()。To ()。WithConstructorArgument(「connString」,「Data Source = something; Initial Catalog = something; uid = something; pwd = something「);'
我知道它錯了,只是想檢查它是否甚至可以運行。令人驚訝的是它開始執行,但連接字符串沒有形成。 – Tarun

回答

0

您可以添加綁定數據庫上下文和指向Ninject使用你的工廠方法:

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

謝謝一噸佩特,它只是像老闆一樣工作。你們有這樣清晰的概念。 :) – Tarun

+0

嗨Peit,我想添加另一個ToMethod,但然後NInject停止工作,通過不給予默認的構造函數錯誤。 ();} 'kernel.Bind ()。ToMethod(_ => TenantDbContext.Create());' 'kernel.Bind ()。ToMethod(__ => MasterDbContext.Create());' – Tarun

+0

It一次只能使用一個「ToMethod」。我怎樣才能使用多個「ToMethod」?謝謝! – Tarun

相關問題