簡単な質問です。
Castle.Windsor、nHibernate、および ASP.NET MVC で UnitOfWork を使用するにはどうすればよいですか?
次に、拡張された詳細について説明します。パターンを理解するための私の探求では、具体的にインストールする必要がある方法に関して、UnitOfWork
と組み合わせて直接的な例を使用するものに出くわすのに苦労しています。Castle.Windsor
ここまでが私の理解です。
IUnitOfWork
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
が使用されることはありません。
Web リクエスト レベルに移行する必要があるとの連絡を受けましたがUnitOfWork
、実際にこれを行う方法を説明するものは見つかりません。私はいかなる種類の a も使用しませんServiceLocator
(私が試したとき、これも悪い習慣だと言われました...)。
混乱 -- はどのよう
UnitOfWork
に作成されるのですか?一般的に、私はこれを理解していません。
UnitOfWork
私の考えでは、コンストラクターに 渡し始めようと考えていRepository
ましたが、それが Web リクエストに含まれる必要がある場合、この 2 つがどこに関係しているのかわかりません。
さらなるコード
これは、質問に対して正しい情報を提供しないという習慣があるように見えるため、明確にするための追加のコードです。
インストーラー
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();
}
}