런타임에 연결 문자열을 전달하여 DBContect 개체를 만들려고합니다. 다음은 NiNject 저장소 구현의 구조입니다.Ninject를 사용하여 리포지토리 생성자에 매개 변수 생성자를 삽입하는 방법은 무엇입니까?
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 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 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 Database에 대한 작업을 수행하기 위해 정확한 Tenant Database 문자열을 전달할 수 있도록 모든 요청시 액세스 토큰에서 Tenant 이름을 가져오고 Tenant 객체를 요청한 캐싱을 수행합니다.
아래 코드에서 요청한 클라이언트의 Tenant Database 문자열을 제공 할 현재 요청 캐시에서 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()", 나는 "어떤 기본 생성자를 찾을 수 없습니다"라고 말하는 예외를 받고 시작합니다. 그것은 단순히 kernal과 두 개의 바인딩을 사용하지 않습니다. 위의 코드를 살펴보고 내가 잘못 가고있는 곳을 알려주십시오.
귀하의 도움에 감사드립니다. 미리 감사드립니다.
합니다. 나는 Ninject를 사용하지 않지만 논리는'커널 [TenantDbContext를 찾을 때]와 같다. [이 생성자를이 connString과 함께 사용] – Jonesopolis
[this answer] (https://stackoverflow.com/questions/35308511)을 보라./how-to-make-ninject-choose-a-specific-constructor-without-inject-injectattribute) – Jonesopolis
당신의 즉각적인 답변에 대해 Jonesopolis에게 감사드립니다. 나는 다음과 같이 제안했다 :(). (). WithConstructorArgument ("connString", "데이터 소스 = 무언가, 초기 카탈로그 = 무언가, uid = 뭔가; pwd = something "); '
'kernel.Bind
나는 그 잘못을 알고 있고, 심지어 전혀 실행되는지 아닌지를 확인하기를 원했다. 놀랍게도 실행을 시작했지만 연결 문자열이 형성되지 않습니다. – Tarun