1

J'essaye de créer l'objet DBContect en passant la chaîne de connexion à l'exécution. Voici la structure de mon implémentation de NiNject Repository.Comment injecter un constructeur de paramètres dans le constructeur Repository en utilisant Ninject?

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

mise en œuvre du référentiel est la suivante:

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 
} 

va ici ma classe TenantDBContext qui prend un argument comme une chaîne de base de données. Aucun constructeur par défaut

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

Enfin, RegisterServices que j'ai dans mes NinjectWebCommons.cs se présente comme suit: Chaque locataire ont sa base de données. Nous extrayons le nom du locataire du jeton d'accès à chaque requête et mettons en cache l'objet Tenant demandé afin que nous puissions transmettre la chaîne de base de données Tenant correcte pour effectuer les opérations sur la base de données des locataires demandée.

Ci-dessous l'extrait, nous récupérons l'objet locataire à partir du cache de requêtes actuel qui nous fournira la chaîne de la base de données du client demandé.

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

Problème: Quand j'ajouter dans mon second élément de liaison NinjectWebCommons.cs « kernel.Bind() », je commence à faire exception en disant que « Aucun constructeur par défaut trouvé ». Il ne prend tout simplement pas deux liaisons avec le noyau. Je vous demande de regarder le code ci-dessus et de me signaler où je me trompe.

J'apprécierai votre aide. Merci d'avance.

+0

vous devez indiquer votre conteneur comment construire votre 'DbContext'. Je n'utilise pas Ninject, mais la logique est comme 'noyau. [Lorsque vous cherchez TenantDbContext]. [Utilisez ce constructeur avec ce connString]' – Jonesopolis

+0

regardez [cette réponse] (https://stackoverflow.com/questions/35308511/how-to-make-ninject-choose-a-specific-constructor-without-using-injectattribute) – Jonesopolis

+0

Merci Jonesopolis pour votre réponse rapide. J'ai essayé de faire ce que vous avez suggéré comme suit:
'kernel.Bind (). (). WithConstructorArgument (" connString "," Source de données = quelque chose; Initial Catalog = quelque chose; uid = quelque chose; pwd = quelque chose ");'
Je sais que c'est faux, je voulais juste vérifier si elle fonctionne même pas du tout ou pas. Étonnamment, il a commencé à s'exécuter, mais la chaîne de connexion ne se forme pas. – Tarun

Répondre

0

Vous pouvez ajouter une liaison pour le contexte de base de données et le point Ninject utiliser votre méthode de création:

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

Merci beaucoup, Peit, ça a juste marché comme un boss. Vous avez un concept si clair. :) – Tarun

+0

Salut Peit, j'essaye d'ajouter un autre ToMethod mais NInject cesse de fonctionner en ne donnant aucune erreur de constructeur par défaut. 'kernel.Bind (). ToMethod (_ => TenantDbContext.Create());' 'kernel.Bind (). ToMethod (__ => MasterDbContext.Create());' – Tarun

+0

It fonctionne avec un seul "ToMethod" à la fois. Comment puis-je utiliser plusieurs "ToMethod"? Merci! – Tarun