我想在運行時通過傳遞連接字符串來創建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()」,我開始變得異常說「沒有默認構造函數找到」。它根本不會與內核綁定。請你請看看上面的代碼,並指出我在哪裏出錯。
我會感謝您的幫助。提前致謝。
你需要告訴你的容器如何建立你的'DbContext'。我不使用Ninject,但是邏輯就像'kernel。[在尋找TenantDbContext時] [用這個connString使用這個構造函數]' – Jonesopolis
看看[這個答案](https://stackoverflow.com/questions/35308511/how-to-make-ninject-choose-a-specific-constructor-without-using-injectattribute) – Jonesopolis
感謝Jonesopolis的及時回覆。我嘗試按照你的建議做如下操作:()。To ()。WithConstructorArgument(「connString」,「Data Source = something; Initial Catalog = something; uid = something; pwd = something「);'
'kernel.Bind
我知道它錯了,只是想檢查它是否甚至可以運行。令人驚訝的是它開始執行,但連接字符串沒有形成。 – Tarun