2015-10-09 8 views
0

Я использую шаблон репозитория/единицы работы с nhibernate и ninject. У меня есть общий репозиторий, и подразделение работает на фабрике сеансов. До сих пор он работал отлично, но теперь я ударил стену. Мой проект теперь требует, чтобы у меня была вторая база данных. Я не могу оборачивать голову тем, как сделать свой репо/единицу работы общим для баз данных. Вот мой код, полученный из here:Несколько баз данных, использующих шаблон репо с ninject и nhibernate

Repository:

public interface IRepository<T> where T : class 
{ 
    IQueryable<T> GetAll(); 
    T GetById(Guid id); 
    void Create(T entity); 
    void Update(T entity); 
    void Delete(Guid id); 
} 

public class Repository<T> : IRepository<T> where T : class 
{ 
    private UnitOfWork _unitOfWork; 
    public Repository(IUnitOfWork unitOfWork) 
    { 
     _unitOfWork = (UnitOfWork)unitOfWork; 
    } 

    protected ISession Session { get { return _unitOfWork.Session; } } 

    // CRUD operations... 
} 

Единица работы:

public interface IUnitOfWork 
{ 
    void BeginTransaction(); 
    void Commit(); 
} 

public class UnitOfWork : IUnitOfWork 
{ 
    private static readonly ISessionFactory _sessionFactory; 
    private ITransaction _transaction; 

    public ISession Session { get; private set; } 

    static UnitOfWork() 
    { 
     // Initialise singleton instance of ISessionFactory, static constructors are only executed once during the 
     // application lifetime - the first time the UnitOfWork class is used 

     _sessionFactory = Fluently.Configure() 
         .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("CONN"))) 
         .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.Load("MyAssembly"))) 
         .CurrentSessionContext<WebSessionContext>() 
         .BuildSessionFactory(); 
    } 

    public UnitOfWork() 
    { 
     Session = _sessionFactory.OpenSession(); 
    } 

    public void BeginTransaction() 
    { 
     _transaction = Session.BeginTransaction(); 
    } 

    public void Commit() 
    { 
     try 
     { 
      _transaction.Commit(); 
     } 
     catch 
     { 
      _transaction.Rollback(); 
      throw; 
     } 
     finally 
     { 
      Session.Close(); 
     } 
    } 
} 

Моя единственная идея иметь отдельный репозиторий и блок рабочих классов для каждого из базы данных. Это кажется мне очень уродливым, так как будет много дублирования кода. Есть ли способ сделать repo/uow generic для уровня базы данных, а также типа объекта?

Мой другой вариант, который я видел, заключается в том, что NCommon может справиться с этим для меня. Я готов принять этот маршрут, если это рекомендуется, но я не был готов сразу же вскочить в постель, так как проект не обновлялся более двух лет.

ответ

1

Взял меня некоторое время, но вот что я придумал в случае, если кто-то нуждается в этом:

Modified Repo:

public interface IRepository<TEntity, TContext> where TEntity : class where TContext : DatabaseContext 
{ 
    IQueryable<TEntity> GetAll(); 
    TEntity GetById(Guid id); 
    void Create(TEntity entity); 
    void Update(TEntity entity); 
    void Delete(Guid id); 
} 

public class Repository<TEntity, TContext> : IRepository<TEntity, TContext> where TEntity : class where TContext : DatabaseContext 
{ 
    private UnitOfWork<TContext> _unitOfWork; 
    public Repository(IUnitOfWork<TContext> unitOfWork) 
    { 
     _unitOfWork = (UnitOfWork<TContext>)unitOfWork; 
    } 

    protected ISession Session { get { return _unitOfWork.Session; } } 

    public IQueryable<TEntity> GetAll() 
    { 
     return Session.Query<TEntity>(); 
    } 

    public TEntity GetById(Guid id) 
    { 
     return Session.Get<TEntity>(id); 
    } 

    public void Create(TEntity entity) 
    { 
     Session.Save(entity); 
    } 

    public void Update(TEntity entity) 
    { 
     Session.Update(entity); 
    } 

    public void Delete(Guid id) 
    { 
     Session.Delete(Session.Load<TEntity>(id)); 
    } 
} 

Modified Единица работы:

public class UnitOfWork<TContext> : IUnitOfWork<TContext> where TContext : DatabaseContext 
{ 
    private ISessionFactory _sessionFactory; 
    private ITransaction _transaction; 

    public ISession Session { get; private set; } 

    public UnitOfWork(TContext context) 
    { 
     if (_sessionFactory == null) 
     { 
      _sessionFactory = context.GetSessionFactory(); 
     } 

     Session = _sessionFactory.OpenSession(); 

    } 

    public void BeginTransaction() 
    { 
     _transaction = Session.BeginTransaction(); 
    } 

    public void Commit() 
    { 
     try 
     { 
      _transaction.Commit(); 
     } 
     catch 
     { 
      _transaction.Rollback(); 
      throw; 
     } 
     finally 
     { 
      Session.Close(); 
     } 
    } 
} 

DatabaseContext:

public interface DatabaseContext 
{ 
    ISessionFactory GetSessionFactory(); 
} 

public class QualityControlDatabaseContext : DatabaseContext 
{ 
    public ISessionFactory GetSessionFactory() 
    { 

     return Fluently.Configure() 
         .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("QCConnection"))) 
         .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.Load("QCEntities"))) 
         .CurrentSessionContext<WebSessionContext>() 
         .BuildSessionFactory(); 
    } 
} 
public class SAPDatabaseContext : DatabaseContext 
{ 
    public ISessionFactory GetSessionFactory() 
    { 

     return Fluently.Configure() 
         .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("SAPConnection"))) 
         .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.Load("SAPEntities"))) 
         .CurrentSessionContext<WebSessionContext>() 
         .BuildSessionFactory(); 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^