Как внедрить различные сеансы NHibernate (multi-db) в один и тот же репозиторий с помощью контроллера, контролирующего, какие сеансы с Ninject - PullRequest
3 голосов
/ 25 ноября 2011

Использование: ASP.NET MVC3 Ninject 2 Fluent nHibernate

У меня есть 2 базы данных (DB1 и DB2).У меня есть один базовый класс репозитория (Repository) и много контроллеров (Controller1, Controller2).

public MyController(IRepository<SomeModelFromDB1> someModelFromDB1Repository, IRepository<SomeModelFromDB2> someModelFromDB2Repository)
{
    [...]
}

public class Repository<T> : IRepository<T> where T : Entity
{
    private readonly ISession _session;

    public Repository(ISessionFactory sessionFactory)
    {
        _session = sessionFactory.OpenSession();
    }
}

public class DB1SessionFactory : ISessionFactory
{
    private readonly NHibernate.ISessionFactory _sessionFactory;

    private ISession _session;

    public DB1SessionFactory()
    {
        [...]
    }
}

public class DB2SessionFactory : ISessionFactory
{
    private readonly NHibernate.ISessionFactory _sessionFactory;

    private ISession _session;

    public DB2SessionFactory()
    {
        [...]
    }
}

Теперь, когда я создаю MyController.Я хочу, чтобы мой репозиторий вводился, но этот репозиторий должен использовать DB1 (или DB2, в зависимости от модели) SessionFactory.

Я не могу понять, как все это правильно внедрить ... Когда у меня был только один SessionFactory (DB1), вот что у меня было с NINJECT:

kernel.Bind<ISessionFactory>().To<DB1SessionFactory>()
            .InRequestScope();

kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>));

Edit:

Лучше всего было бы, чтобы в хранилище вводился правильный сеанс в зависимости от модели.Поскольку некоторые модели взяты из DB1, а другие из DB2, выбор должен зависеть от него.Было бы также замечательно, если бы разработчику контроллера / представления не пришлось беспокоиться о чем-либо (например, иметь [Named] перед хранилищем), но если это то, что нужно.Даже с [Named] я не мог понять, как внедрить правильный сеанс в хранилище на основе хранилища [Named] в контроллере ...

1 Ответ

3 голосов
/ 25 ноября 2011

Прежде всего, вы должны определить фабрику сеанса в одной области видимости и иметь сеанс в области запроса.

Выполните настройку следующим образом:

.Bind<ISessionFactory>().To<DB1SessionFactory>().Named("DB1")
     .InSingletonScope();

.Bind<ISessionFactory>().To<DB2SessionFactory>().Named("DB2")
     .InSingletonScope();

private bool IsOnDB(IRequest request, string dbName)
{
    var repositoryType = request.ParentRequest.Service;
    var modelType = repositoryType.GetGenericArguments()[0];
    var databaseName = this.GetDatabaseForModel(modelType);

    return databaseName == dbName;
}

.Bind<ISession>()
    .ToMethod(ctx => ctx.Kernel.Get<ISessionProvider>("DB1").OpenSession())
    .When(r => this.IsOnDb(r, "DB1"))
    .InRequestScope();
.Bind<ISession>()
    .ToMethod(ctx => ctx.Kernel.Get<ISessionProvider>("DB2").OpenSession())
    .When(r => this.IsOnDb(r, "DB2"))
    .InRequestScope();
...