#c# #asp.net-mvc-2 #dependency-injection #ioc-container #ninject
#c# #asp.net-mvc-2 #внедрение зависимостей #ioc-контейнер #ninject
Вопрос:
Итак, используя некоторую помощь из руководств, мне удалось подключить сеанс Nhibernate к моим репозиториям, а мои репозитории — к моим контроллерам, используя Ninject. Однако есть один момент настройки, из-за которого я не понимаю «автоматической магии» того, что делает Ninject, и надеялся, что кто-нибудь сможет объяснить.
Ниже приведен мой Ninject ModuleRepository, который наследуется от NinjectModule, который выполняет всю привязку.
public class ModuleRepository : NinjectModule
{
public override void Load()
{
var helper = new NHibernateHelper(ConfigurationManager.ConnectionStrings[Environment.MachineName].ConnectionString);
Bind<ISessionFactory>().ToConstant(helper.SessionFactory)
.InSingletonScope();
Bind<IUnitOfWork>().To<UnitOfWork>()
.InRequestScope();
Bind<ISession>().ToProvider<SessionProvider>()
.InRequestScope();
Bind<IRepository<Product>>().To<ProductRepository>();
Bind<IRepository<Category>>().To<CategoryRepository>();
}
}
Вот класс UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly ISessionFactory _sessionFactory;
private readonly ITransaction _transaction;
public ISession Session { get; private set; }
public UnitOfWork(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
//Open Session
Session = _sessionFactory.OpenSession();
Session.FlushMode = FlushMode.Auto;
_transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
}
public void Commit()
{
if (!_transaction.IsActive)
throw new InvalidOperationException("There is no active Transaction");
_transaction.Commit();
}
public void Rollback()
{
if (_transaction.IsActive)
_transaction.Rollback();
}
//Close open session
public void Dispose()
{
Session.Close();
}
}
Итак, я понимаю, что мы создаем постоянный экземпляр объекта, который создает Nhibernate SessionFactory. Ниже приведен класс SessionProvider, который возвращает сеанс из объекта UnitOfWork, который оборачивает каждую единицу работы в транзакцию.
SessionProvider
public class SessionProvider : Provider<ISession>
{
protected override ISession CreateInstance(IContext context)
{
var unitOfWork = (UnitOfWork)context.Kernel.Get<IUnitOfWork>();
return unitOfWork.Session;
}
}
Репозитории принимают ISession в своем конструкторе. Но чего я не вижу, так это того, как UnitOfWork.Session является «сеансом», который передается в мои репозитории?
Любая помощь в понимании этого была бы отличной. Спасибо.
Ответ №1:
Привязка с использованием:
Bind<ISession>().ToProvider<SessionProvider>().InRequestScope();
указывает, что он должен поддерживать область запроса. Это означает, что Ninject будет кэшировать все запросы для ISession в течение всего HttpRequest — таким образом, все внедряемые классы (или явно получающие экземпляр) будут использовать один и тот же экземпляр ISession. В вашей конфигурации то же самое касается IUnitOfWork.
Смотрите Этот пост Нейта Кохари для описания различных объектов области видимости в Ninject.