Простой вопрос.
Как мне использовать UnitOfWork с Castle.Windsor, nHibernate и ASP.NET MVC?
Теперь о расширенные детали. В своем стремлении понять шаблон UnitOfWork
мне трудно найти что-либо, в котором используется прямой пример в сочетании с Castle.Windsor
, особенно в отношении того, как это нужно быть установлен.
Вот мое понимание.
IUnitOfWork
используется для объявления шаблона UnitOfWork
должен Commit
и Откат
транзакций и открытие сеанса
. Итак, с учетом сказанного, вот мой IUnitOfWork
. (Я использую Fluent nHibernate
)
public interface IUnitOfWork : IDisposable
{
ISession Session { get; private set; }
void Rollback();
void Commit();
}
Итак, вот мой Castle.Windsor
Загрузчик контейнера (ASP.NET MVC)
public class WindsorContainerFactory
{
private static Castle.Windsor.IWindsorContainer container;
private static readonly object SyncObject = new object();
public static Castle.Windsor.IWindsorContainer Current()
{
if (container == null)
{
lock (SyncObject)
{
if (container == null)
{
container = new Castle.Windsor.WindsorContainer();
container.Install(new Installers.SessionInstaller());
container.Install(new Installers.RepositoryInstaller());
container.Install(new Installers.ProviderInstaller());
container.Install(new Installers.ControllerInstaller());
}
}
}
return container;
}
}
Итак, теперь в моем Global. asax
файл, У меня есть следующие ...
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Register the Windsor Container
ControllerBuilder.Current
.SetControllerFactory(new Containers.WindsorControllerFactory());
}
Теперь я понимаю, что мне нужно передать ISession
в мой Репозиторий. Итак, позвольте мне предположить IMembershipRepository
.
class MembershipRepository : IMembershipRepository
{
private readonly ISession session;
public MembershipRepository(ISession session)
{
this.session = session;
}
public Member RetrieveMember(string email)
{
return session.Query<Member>().SingleOrDefault( i => i.Email == email );
}
}
Итак, я запутался. При использовании этого метода ISession
не уничтожается должным образом, а UnitOfWork
никогда не используется.
Мне сообщили, что UnitOfWork
необходимо перейти на уровень веб-запросов, но я не могу найти ничего, что объясняло бы, как это сделать. Я не использую ServiceLocator
какого-либо вида (когда я пытался, мне сказали, что это тоже плохая практика ...).
Путаница - Как
UnitOfWork
создать?Я просто не понимаю этого, в
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); // Register the Windsor Container ControllerBuilder.Current .SetControllerFactory(new Containers.WindsorControllerFactory()); }
Репозиторий
Теперь я понимаю, что мне нужно передать
ISession
моему репозиторию. Итак, позвольте мне предположитьIMembershipRepository
.class MembershipRepository : IMembershipRepository { private readonly ISession session; public MembershipRepository(ISession session) { this.session = session; } public Member RetrieveMember(string email) { return session.Query<Member>().SingleOrDefault( i => i.Email == email ); } }
Итак, я запутался. При использовании этого метода
ISession
не уничтожается должным образом, аUnitOfWork
никогда не используется.Мне сообщили, что
UnitOfWork
необходимо перейти на уровень веб-запросов, но я не могу найти ничего, что объясняло бы, как это сделать. Я не используюServiceLocator
какого-либо типа (когда я пытался, мне сказали, что это тоже плохая практика ...).Путаница - Как
UnitOfWork
создать?Я просто не понимаю этого, в
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); // Register the Windsor Container ControllerBuilder.Current .SetControllerFactory(new Containers.WindsorControllerFactory()); }
Репозиторий
Теперь я понимаю, что мне нужно передать
ISession
моему репозиторию. Итак, позвольте мне предположитьIMembershipRepository
.class MembershipRepository : IMembershipRepository { private readonly ISession session; public MembershipRepository(ISession session) { this.session = session; } public Member RetrieveMember(string email) { return session.Query<Member>().SingleOrDefault( i => i.Email == email ); } }
Итак, я запутался. При использовании этого метода сессия
ISession
не удаляется должным образом, аUnitOfWork
никогда не используется.Мне сообщили, что
UnitOfWork
необходимо перейти на уровень веб-запросов, но я не могу найти ничего, что объясняло бы, как это сделать. Я не используюServiceLocator
какого-либо вида (когда я пытался, мне сказали, что это тоже плохая практика ...).Путаница - Как
UnitOfWork
создать?Я просто не понимаю этого, в позвольте мне предположить
IMembershipRepository
.class MembershipRepository : IMembershipRepository { private readonly ISession session; public MembershipRepository(ISession session) { this.session = session; } public Member RetrieveMember(string email) { return session.Query<Member>().SingleOrDefault( i => i.Email == email ); } }
Итак, я запутался. При использовании этого метода
ISession
не уничтожается должным образом, аUnitOfWork
никогда не используется.Мне сообщили, что
UnitOfWork
необходимо перейти на уровень веб-запросов, но я не могу найти ничего, что объясняло бы, как это сделать. Я не используюServiceLocator
какого-либо типа (когда я пытался, мне сказали, что это тоже плохая практика ...).Путаница - Как
UnitOfWork
создать?Я просто не понимаю этого, в позвольте мне предположить
IMembershipRepository
.class MembershipRepository : IMembershipRepository { private readonly ISession session; public MembershipRepository(ISession session) { this.session = session; } public Member RetrieveMember(string email) { return session.Query<Member>().SingleOrDefault( i => i.Email == email ); } }
Итак, я запутался. При использовании этого метода
ISession
не уничтожается должным образом, аUnitOfWork
никогда не используется.Мне сообщили, что
UnitOfWork
необходимо перейти на уровень веб-запросов, но я не могу найти ничего, что объясняло бы, как это сделать. Я не используюServiceLocator
какого-либо типа (когда я пытался, мне сказали, что это тоже плохая практика ...).Путаница - Как
UnitOfWork
создать?Я просто не понимаю этого, в нас проинформировали о том, что
UnitOfWork
необходимо перейти на уровень веб-запросов, но я не могу найти ничего, что объясняло бы, как это сделать. Я не используюServiceLocator
какого-либо вида (когда я пытался, мне сказали, что это тоже плохая практика ...).Путаница - Как
UnitOfWork
создать?Я просто не понимаю этого, в нас проинформировали о том, что
UnitOfWork
необходимо перейти на уровень веб-запросов, но я не могу найти ничего, что объясняло бы, как это сделать. Я не используюServiceLocator
какого-либо вида (когда я пытался, мне сказали, что это тоже плохая практика ...).Путаница - Как
UnitOfWork
создать?Я просто не понимаю этого, в Общее. Я думал, что буду начните передавать
UnitOfWork
вКонструкторы репозитория
- но если он нужно указать в веб-запросе, я не понимание того, где они соотносятся.Дополнительный код
Это дополнительный код для пояснения просто потому, что у меня, кажется, есть привычка никогда не предоставлять правильную информацию по моим вопросам.
Установщики
public class ControllerInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( AllTypes.FromThisAssembly() .BasedOn<IController>() .Configure(c => c.LifeStyle.Transient)); } } public class ProviderInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Component .For<Membership.IFormsAuthenticationProvider>() .ImplementedBy<Membership.FormsAuthenticationProvider>() .LifeStyle.Singleton ); } } public class RepositoryInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Component .For<Membership.IMembershipRepository>() .ImplementedBy<Membership.MembershipRepository>() .LifeStyle.Transient ); container.Register( Component .For<Characters.ICharacterRepository>() .ImplementedBy<Characters.CharacterRepository>() .LifeStyle.Transient ); } } public class SessionInstaller : Castle.MicroKernel.Registration.IWindsorInstaller { private static ISessionFactory factory; private static readonly object SyncObject = new object(); public void Install(Castle.Windsor.IWindsorContainer container, IConfigurationStore store) { container.Register( Component.For<ISessionFactory>() .UsingFactoryMethod(SessionFactoryFactory) .LifeStyle.Singleton ); container.Register( Component.For<ISession>() .UsingFactoryMethod(c => SessionFactoryFactory().OpenSession()) .LifeStyle.Transient ); } private static ISessionFactory SessionFactoryFactory() { if (factory == null) lock (SyncObject) if (factory == null) factory = Persistence.SessionFactory.Map(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["Remote"].ConnectionString); return factory; } }
UnitOfWork
Вот мой класс
UnitOfWork
дословно.public class UnitOfWork : IUnitOfWork { private readonly ISessionFactory sessionFactory; private readonly ITransaction transaction; public UnitOfWork(ISessionFactory sessionFactory) { this.sessionFactory = sessionFactory; Session = this.sessionFactory.OpenSession(); transaction = Session.BeginTransaction(); } public ISession Session { get; private set; } public void Dispose() { Session.Close(); Session = null; } public void Rollback() { if (transaction.IsActive) transaction.Rollback(); } public void Commit() { if (transaction.IsActive) transaction.Commit(); } }