简单的问题。
如何将 UnitOfWork 与 Castle.Windsor、nHibernate 和 ASP.NET MVC 一起使用?
现在了解详细信息。在我寻求理解该UnitOfWork
模式的过程中,我很难遇到任何使用直接示例与 结合使用的东西Castle.Windsor
,特别是关于它需要安装的方式。
到目前为止,这是我的理解。
工作单位
- 该
IUnitOfWork
接口用于声明模式 - 类
UnitOfWork
必须Commit
和Rollback
事务,并暴露一个Session
。
话虽如此,这是我的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
需要进入 Web 请求级别 - 但我找不到任何解释如何实际执行此操作的内容。我不使用ServiceLocator
任何类型的(当我尝试时,有人告诉我这也是不好的做法......)。
困惑——如何
UnitOfWork
创建一个?我只是不明白这一点,一般来说。我的想法是我将开始传递
UnitOfWork
给Repository
构造函数 - 但如果它必须进入 Web 请求,我不明白两者之间的关系。
更多代码
这是用于澄清的额外代码,仅仅是因为我似乎有从不为我的问题提供正确信息的习惯。
安装人员
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
课堂逐字记录。
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();
}
}