1

런타임에 연결 문자열을 전달하여 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과 두 개의 바인딩을 사용하지 않습니다. 위의 코드를 살펴보고 내가 잘못 가고있는 곳을 알려주십시오.

귀하의 도움에 감사드립니다. 미리 감사드립니다.

+0

합니다. 나는 Ninject를 사용하지 않지만 논리는'커널 [TenantDbContext를 찾을 때]와 같다. [이 생성자를이 connString과 함께 사용] – Jonesopolis

+0

[this answer] (https://stackoverflow.com/questions/35308511)을 보라./how-to-make-ninject-choose-a-specific-constructor-without-inject-injectattribute) – Jonesopolis

+0

당신의 즉각적인 답변에 대해 Jonesopolis에게 감사드립니다. 나는 다음과 같이 제안했다 :
'kernel.Bind (). (). WithConstructorArgument ("connString", "데이터 소스 = 무언가, 초기 카탈로그 = 무언가, uid = 뭔가; pwd = something "); '
나는 그 잘못을 알고 있고, 심지어 전혀 실행되는지 아닌지를 확인하기를 원했다. 놀랍게도 실행을 시작했지만 연결 문자열이 형성되지 않습니다. – Tarun

답변

0

당신은 데이터베이스 컨텍스트에 대한 바인딩을 추가하고 공장 방법을 사용해서 Ninject를 가리킬 수 있습니다 : 당신이 당신의`DbContext`을 구축하는 방법을 컨테이너 말할 필요

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

고마워요, 핏. 그냥 상사처럼 일 했어. 너희들은 그런 명확한 개념을 가지고있다. :) – Tarun

+0

안녕하세요 Peit, 다른 ToMethod를 추가하려고하지만 NInject가 기본 생성자 오류를주지 않아 작업을 중지합니다. 커널 _Bind (). ToMethod (__ => MasterDbContext.Create()); ' – Tarun

+0

It' 한 번에 하나의 "ToMethod"로만 작동합니다. 어떻게 여러 개의 "ToMethod"를 사용할 수 있습니까? 감사! – Tarun

관련 문제