Mit mehreren dbcontext-Instanzen und dependency injection

Dies ist eine ähnliche Frage, die ich hier vor ein paar Wochen mit einer signifikanten änderung in der Anforderung.

Habe ich eine neue und einzigartige (ich habe nicht gefunden, was so in meinem stackoverflow-Suche) fachliche Anforderung:

Habe ich erstellt zwei separate entity framework 6 DbContexts, dass zwei strukturell verschiedenen Datenbanken, nennen wir Sie PcMaster und PcSubs. Während PcMaster ist eine geradlinig-Datenbank und die PcMasterContext wird eine statische Verbindungszeichenfolge, PcSubs-Datenbank dient als Vorlage zum erstellen von neuen Datenbanken aus. Offensichtlich, da die kopierten Datenbanken haben die gleiche Struktur, die Idee ist, ändern Sie einfach die Datenbank (Katalog) Namen in der Verbindungszeichenfolge auf eine andere db als die dbcontext instanziiert wird. Ich habe auch repository-pattern und dependency injection (derzeit Ninject, aber das denken der Umzug in Autofac).

Ich habe nicht gesehen, eine IDbContext Schnittstelle für DbContext, es sei denn, Sie wollen selbst eines erstellen. Aber dann habe ich gesehen, viele sagen, dass es nicht eine gute Idee ist oder nicht die beste Praxis.

Im Grunde, was ich tun möchte, ist, unter bestimmten Bedingungen, nicht nur die Anwendung wechseln muss zwischen PCMasterContext und PCSubsContext, sondern auch ändern Sie die Verbindungszeichenfolge, um PCSubsContext wenn PCSubsContext ist der aktuelle Kontext. die dbContext ich verwendet in das repository muss auf eine andere Datenbank. Ich weiß nicht, wie ich können dies tun, mit einem IoC-container wie Ninject oder Autofac. Hier sind einige code-Schnipsel, die ich bisher erstellt haben. Helfen Sie mit einige wirklich funktionierende Lösungen ist hoch geschätzt.

Hier ist mein interface für die base-repository

public interface IPCRepositoryBase<T> where T : class
{
  void Add(T entity);
  void Delete(T entity);
  T FindOne(Expression<Func<T, bool>> predicate);
  IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
  IQueryable<T> GetAll();
  void SetConnection(string connString);
  //... 
  //...
}

Hier ist meine Zusammenfassung repository base

public abstract class PCRepositoryBase<T> : IPCRepositoryBase<T>, IDisposable where T : class
{
  protected readonly IDbSet<T> dbSet;
  protected DbContext dbCtx;

  public PCRepositoryBase(DbContext dbCtx)
  {
     this.dbCtx = dbCtx;
     dbSet = dbCtx.Set<T>();
  }
  public void SetConnection(string connString)
  {
     dbCtx.Database.Connection.ConnectionString = connString;
  }
  public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate)
  {
     return dbSet.Where(predicate); //DataContext.Set<T>().Where( predicate  );
  }
  public virtual IQueryable<T> GetAll()
  {
     return dbSet;
  }
  public T FindOne(Expression<Func<T, bool>> predicate)
  {
     return dbSet.SingleOrDefault(predicate);
  }
  //... Not all implementations listed
  //...
}

Und nun, hier ist die Schnittstelle für eine der abgeleiteten repositories:

public interface ISubscriberRepository : IPCRepositoryBase<Subscriber>
{
  IQueryable<Subscriber> GetByStatusName( PCEnums.enumSubsStatusTypes status   );
  IQueryable<Subscriber> GetByBusinessName( string businessName );
  //...
  //...
}

public class SubscriberRepository : PCRepositoryBase<Subscriber>, ISubscriberRepository
{
  public SubscriberRepository( DbContext context ) : base( context ) { }
  public IQueryable<Subscriber> GetByStatusName( PCEnums.enumSubsStatusTypes    status )
  {
     return FindBy(x => x.SubsStatusType.Name == status.ToString());
  }
  public IQueryable<Subscriber> GetByBusinessName( string businessName )
  {
     return FindBy( s => s.BusinessName.ToUpper() == businessName.ToUpper()  );
  }
  //... other operations omitted for brevity!
}

Nun, meine PCSubs dbContext generiert der designer:

public partial class PCSubsDBContext : DbContext
{
    public PCSubsDBContext() : base("name=PCSubsDBContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<Currency> Currencies { get; set; }
    public virtual DbSet<DurationName> DurationNames { get; set; }
    public virtual DbSet<Subscriber> Subscribers { get; set; }
}

Gibt es eine Möglichkeit, ich kann Sie einfach verwenden und/oder injizieren eine generische dbcontext für beide Datenbanken zusammen mit den Verbindungs-string für verschiedene Datenbanken. Wie würde ich die Eintragung der "DbContext" in der Ioc container ohne eine entsprechende Benutzeroberfläche und noch in der Lage zu injizieren, die Verbindungszeichenfolge zur Laufzeit? Einige code-Beispiele, die wirklich helfen.

Schreibe einen Kommentar