使用带有ninject和nhibernate的repo模式的多个数据库

使用带有ninject和nhibernate的repo模式的多个数据库,nhibernate,ninject,repository-pattern,unit-of-work,Nhibernate,Ninject,Repository Pattern,Unit Of Work,我正在使用nhibernate和ninject的存储库/工作单元模式。我有一个通用存储库,工作单元提供会话工厂。到目前为止,它一直工作得很好,但现在我遇到了困难。我的项目现在要求我有第二个数据库。我不知道如何使我的回购/工作单元也适用于数据库。这是我的代码,来自: 存储库: public interface IRepository<T> where T : class { IQueryable<T> GetAll(); T GetById(Guid id)

我正在使用nhibernate和ninject的存储库/工作单元模式。我有一个通用存储库,工作单元提供会话工厂。到目前为止,它一直工作得很好,但现在我遇到了困难。我的项目现在要求我有第二个数据库。我不知道如何使我的回购/工作单元也适用于数据库。这是我的代码,来自:

存储库:

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...
}
公共接口i假设,其中T:class
{
IQueryable GetAll();
T GetById(Guid id);
无效创建(T实体);
无效更新(T实体);
作废删除(Guid id);
}
公共类存储库:IRepository,其中T:class
{
私人工作单位(Unitof Work);;
公共存储库(IUnitOfWork unitOfWork)
{
_unitOfWork=(unitOfWork)unitOfWork;
}
受保护的ISession会话{get{return\u unitOfWork.Session;}
//积垢操作。。。
}
工作单位:

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();
        }
    }
}
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();
        }
    }
}
公共接口IUnitOfWork
{
void beginsaction();
无效提交();
}
公共类UnitOfWork:IUnitOfWork
{
私有静态只读ISessionFactory _sessionFactory;
私人ITransaction_交易;
公共ISession会话{get;private set;}
静态工作单元()
{
//初始化ISessionFactory的singleton实例,静态构造函数在初始化过程中只执行一次
//应用程序生存期-第一次使用UnitOfWork类
_sessionFactory=fluntly.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c=>c.fromConnectionString WithKey(“CONN”))
.Mappings(m=>m.FluentMappings.AddFromAssembly(Assembly.Load(“MyAssembly”))
.CurrentSessionContext()
.BuildSessionFactory();
}
公共工作单元()
{
会话=_sessionFactory.OpenSession();
}
公共无效开始生效()
{
_事务=Session.BeginTransaction();
}
公共无效提交()
{
尝试
{
_Commit();
}
抓住
{
_transaction.Rollback();
投掷;
}
最后
{
Session.Close();
}
}
}
我唯一的想法是为每个数据库提供单独的存储库和工作单元类。这对我来说真的很难看,因为这将是大量的代码重复。有没有办法使repo/uow在数据库级别和实体类型上通用


我看到的另一个选择是NCommon可能能够为我处理这个问题。如果推荐的话,我愿意走这条路,但我还没有准备好马上就上床睡觉,因为这个项目已经两年多没有更新了。

我花了一段时间,但我想到了以下几点,以防其他人需要:

修改回购协议:

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));
    }
}
public interface i假设where tenty:class where TContext:DatabaseContext
{
IQueryable GetAll();
tenty GetById(Guid id);
无效创建(tenty实体);
无效更新(潜在实体);
作废删除(Guid id);
}
公共类存储库:IRepository where tenty:class where TContext:DatabaseContext
{
私人工作单位(Unitof Work);;
公共存储库(IUnitOfWork unitOfWork)
{
_unitOfWork=(unitOfWork)unitOfWork;
}
受保护的ISession会话{get{return\u unitOfWork.Session;}
公共IQueryable GetAll()
{
返回Session.Query();
}
公共权限GetById(Guid id)
{
返回会话.Get(id);
}
公共void创建(TEntity实体)
{
Session.Save(实体);
}
公共无效更新(TEntity实体)
{
更新(实体);
}
公共无效删除(Guid id)
{
Session.Delete(Session.Load(id));
}
}
修改后的工作单位:

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();
        }
    }
}
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();
        }
    }
}
公共类UnitOfWork:IUnitOfWork其中TContext:DatabaseContext
{
私人ISessionFactory(sessionFactory);;
私人ITransaction_交易;
公共ISession会话{get;private set;}
公共工作单元(TContext上下文)
{
if(_sessionFactory==null)
{
_sessionFactory=context.GetSessionFactory();
}
会话=_sessionFactory.OpenSession();
}
公共无效开始生效()
{
_事务=Session.BeginTransaction();
}
公共无效提交()
{
尝试
{
_Commit();
}
抓住
{
_transaction.Rollback();
投掷;
}
最后
{
Session.Close();
}
}
}
数据库上下文:

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();
    }
}
公共接口数据库上下文
{
ISessionFactory GetSessionFactory();
}
公共类QualityControlDatabaseContext:DatabaseContext
{
公共ISessionFactory GetSessionFactory()
{
流畅地返回。Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c=>c.fromConnectionString WithKey(“QCConnection”))
.Mappings(m=>m.FluentMappings.AddFromAssembly(Assembly.Load(“QCEntities”))
.CurrentSessionContext()
.BuildSessionFactory();
}
}
公共类SAPDatabaseContext:DatabaseContext
{
公共ISessionFactory GetSessionFactory()
{
流畅地返回。Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c=>c.fromConnectionString WithKey(“SAPConnection”))
.Mappings(m=>m.FluentMappings.AddFromAssembly(Assembly.Load(“SAPEntities”))
.CurrentSessionContext()
.BuildSessionFactory();
}
}

我的解决方案与Nick相同,但我将从存储库中删除以了解哪个工作单元,但我使用实体上的属性来了解它属于哪个工作单元
builder.RegisterType<UnitOfWorkFactoryMain>().SingleInstance();
        builder.RegisterType<UnitOfWorkFactorySecondary>().SingleInstance();

        builder.Register(c => new UnitOfWork(c.Resolve<UnitOfWorkFactoryMain>()))
            .Keyed<IUnitOfWork>(Database.System).InstancePerLifetimeScope();
        builder.Register(c => new UnitOfWork(c.Resolve<UnitOfWorkFactorySecondary>()))
            .Keyed<IUnitOfWork>(Database.Secondary).InstancePerLifetimeScope();