Mit mehreren DbContexts mit einem generischen repository und unit of work

Meine Bewerbung wird immer größer und so weit ich habe ein Einzelzimmer MyDbContext muss, die alle Tabellen die ich brauche in meiner Anwendung. Ich möchte (aus Gründen der übersicht) Sie Aufteilung in mehrere DbContext wie MainDbContext, EstateModuleDbContext, AnotherModuleDbContext und UserDbContext.

Ich bin nicht sicher, wie dies geschieht vermutlich, wie ich jetzt bin mit dependecy injection (ninject), um meinen DbContext auf meine UnitOfWork-Klasse wie:

kernel.Bind(typeof(IUnitOfWork)).To(typeof(UnitOfWork<MyDbContext>));

Sollte ich ablegen dieser Ansatz mit dependency injection und explizite setzen der DbContext ich möchte auf meine Leistungen wie:

private readonly EstateService _estateService;

public HomeController()
{
    IUnitOfWork uow = new UnitOfWork<MyDbContext>();
    _estateService = new EstateService(uow);
}

Statt:

private readonly EstateService _estateService;

public HomeController(IUnitOfWork uow)
{
    _estateService = new EstateService(uow);
}

Oder gibt es einen anderen besseren Ansatz? Auch als Zwischenfrage, ich dont wie an der uow zu meinem service - gibt es einen anderen (besseren) Ansatz?

Code

Ich habe diese IDbContext und MyDbContext:

public interface IDbContext
{
    DbSet<T> Set<T>() where T : class;

    DbEntityEntry<T> Entry<T>(T entity) where T : class;

    int SaveChanges();

    void Dispose();
}

public class MyDbContext : DbContext, IDbContext
{
    public DbSet<Table1> Table1 { get; set; }
    public DbSet<Table2> Table1 { get; set; }
    public DbSet<Table3> Table1 { get; set; }
    public DbSet<Table4> Table1 { get; set; }
    public DbSet<Table5> Table1 { get; set; }
    /* and so on */

    static MyDbContext()
    {
        Database.SetInitializer<MyDbContext>(new CreateDatabaseIfNotExists<MyDbContext>());
    }

    public MyDbContext()
        : base("MyDbContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

    }
}

Dann habe ich das IRepository und die Umsetzung:

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();

    void Add(T entity);

    void Delete(T entity);

    void DeleteAll(IEnumerable<T> entity);

    void Update(T entity);

    bool Any();
}

public class Repository<T> : IRepository<T> where T : class
{
    private readonly IDbContext _context;
    private readonly IDbSet<T> _dbset;

    public Repository(IDbContext context)
    {
        _context = context;
        _dbset = context.Set<T>();
    }

    public virtual IQueryable<T> GetAll()
    {
        return _dbset;
    }

    public virtual void Add(T entity)
    {
        _dbset.Add(entity);
    }

    public virtual void Delete(T entity)
    {
        var entry = _context.Entry(entity);
        entry.State = EntityState.Deleted;
        _dbset.Remove(entity);
    }

    public virtual void DeleteAll(IEnumerable<T> entity)
    {
        foreach (var ent in entity)
        {
            var entry = _context.Entry(ent);
            entry.State = EntityState.Deleted;
            _dbset.Remove(ent);
        }
    }

    public virtual void Update(T entity)
    {
        var entry = _context.Entry(entity);
        _dbset.Attach(entity);
        entry.State = EntityState.Modified;
    }

    public virtual bool Any()
    {
        return _dbset.Any();
    }
}

Und die IUnitOfWork und umgesetzt, die Griffe der Arbeit mit dem DbContext

public interface IUnitOfWork : IDisposable
{
    IRepository<TEntity> GetRepository<TEntity>() where TEntity : class;

    void Save();
}

public class UnitOfWork<TContext> : IUnitOfWork where TContext : IDbContext, new()
{
    private readonly IDbContext _ctx;
    private readonly Dictionary<Type, object> _repositories;
    private bool _disposed;

    public UnitOfWork()
    {
        _ctx = new TContext();
        _repositories = new Dictionary<Type, object>();
        _disposed = false;
    }

    public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
    {
        //Checks if the Dictionary Key contains the Model class
        if (_repositories.Keys.Contains(typeof(TEntity)))
        {
            //Return the repository for that Model class
            return _repositories[typeof(TEntity)] as IRepository<TEntity>;
        }

        //If the repository for that Model class doesn't exist, create it
        var repository = new Repository<TEntity>(_ctx);

        //Add it to the dictionary
        _repositories.Add(typeof(TEntity), repository);

        return repository;
    }

    public void Save()
    {
        _ctx.SaveChanges();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (this._disposed) return;

        if (disposing)
        {
            _ctx.Dispose();
        }

        this._disposed = true;
    }
} 
Gibt es irgendwelche logischen Nähte für die Aufteilung der Daten auf mehrere dbcontexts? Wenn Sie dies tun, werden Sie nicht in der Lage sein, die navigation oder eine Sammlung von Eigenschaften, cross-Kontexten (zum Beispiel können Sie nicht tun, ein EF Beziehung zwischen einer Entität in MainDbContext und anderen Entität in UsersDbContext).
Was ist der Grund für die Spaltung der Kontext überhaupt? Auch wenn Sie sich aufteilen , können Sie nicht verwenden, DI. Ich wußte auch nicht, wie Sie Ihre Einheit von Arbeit mit Respository heruntergeladen werden(Wörterbuch-Sache)
Ich werde mehrere Module in meiner Anwendung, und eben nicht zu verschmutzen MyDbContext mit einer Menge von Modulen, die DbSets. Vielleicht sollte ich einfach ignorieren?
Hallo Dan, können Sie vorschlagen, eine bessere Ansatz. Ich bin offen für Vorschläge
Ich wollte dies streng, weil 'IdentityDbContext' (MVC5 & OWIN) mit den Transaktionen, die meine 'AppDbContext'. Der UserManager ist zu finden und gut, aber ich hätte gerne ein wenig mehr Kontrolle, wenn man lose gekoppelte relationale Daten zwischen den beiden.

InformationsquelleAutor janhartmann | 2013-12-12

Schreibe einen Kommentar