Я пытаюсь реализовать шаблон UnitOfWork и Repository с помощью NHibernate. Я ищу лучший способ обмена сеансом между экземпляром экземпляра рабочей единицы и экземпляром репозитория.Обмен сеансом NHibernate между UnitOfWork и репозиторием
Наиболее очевидным способом является введение ThreadStatic
свойства в UnitOfWork
класса
public class UnitOfWork : IUnitOfWork
{
public static UnitOfWork Current
{
get { return _current; }
set { _current = value; }
}
[ThreadStatic]
private static UnitOfWork _current;
public ISession Session { get; private set; }
//other code
}
, а затем в Repository
классе:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected ISession Session { get { return UnitOfWork.Current.Session; } }
//other code
}
Однако мне не нравится реализация перечисленных выше, и решил найти другой способ сделать то же самое.
Так я пришел со вторым способом:
public interface ICurrentSessionProvider : IDisposable
{
ISession CurrentSession { get; }
ISession OpenSession();
void ReleaseSession();
}
public class CurrentSessionProvider : ICurrentSessionProvider
{
private readonly ISessionFactory _sessionFactory;
public CurrentSessionProvider(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
}
public ISession OpenSession()
{
var session = _sessionFactory.OpenSession();
CurrentSessionContext.Bind(session);
return session;
}
public void Dispose()
{
CurrentSessionContext.Unbind(_sessionFactory);
}
public ISession CurrentSession
{
get
{
if (!CurrentSessionContext.HasBind(_sessionFactory))
{
OnContextualSessionIsNotFound();
}
var contextualSession = _sessionFactory.GetCurrentSession();
if (contextualSession == null)
{
OnContextualSessionIsNotFound();
}
return contextualSession;
}
}
private static void OnContextualSessionIsNotFound()
{
throw new InvalidOperationException("Session is not opened!");
}
}
где ISessionFactory
является одноточечно разрешаться autofac и CurrentSessionContext
является CallSessionContext
. Затем я добавляю ICurrentSessionProvider
в конструкторы классов UnitOfWork
и Repository
и пользуюсь свойством CurrentSession
.
Оба подхода, похоже, работают нормально. Поэтому мне интересно, есть ли другие способы реализовать это? Какова наилучшая практика обмена сеансом между единицей работы и хранилищем?
Было надеяться, что вы можете предоставить образец кода для настройки этой конкретной архитектуры! – adaam
Эй, я сейчас спешу, но, возможно, следующий очень упрощенный образец поможет вам начать работу (посмотрю, смогу ли я его обновить позже): https://gist.github.com/anonymous/ ebd36d4a39c2ed45dd20824d849f89f7 –