, 할 수있을 것입니다 (MVC + NHibernate에 사이트와 표준 관행으로 보인다) 내가 일하고 프로젝트는 UnitOfWork에는 전체 세션에 대해 정의하고있다
항목 모음을 반복하고 자신의 "로컬"트랜잭션에서 하나씩 차례대로 처리하십시오. 이 같은
뭔가 다음 들어 BeginTransaction 라인은 같은 "외부"세션을 사용하고 있기 때문에
foreach(var item in CollectionOfItems)
{
using (ITransaction transaction = UnitOfWork.CurrentSession.BeginTransaction())
{
//do work on item. rollback on failure,
//but it should not affect the other items
}
}
는하지만이 작동하지 않습니다. 작은 코드 블록에서 트랜잭션을 수행 할 수있는 자체 "로컬"세션을 얻으려면 어떻게해야합니까? 세션이 다음 코드에서 작업 단위로 주입되고 있다고 생각합니다. 컨트롤러가 응답을 반환 그래서 때마다
For<IUnitOfWork>().LifecycleIs(new HybridLifecycle())
.Use<UnitOfWork>();
, 세션 :
의 UnitOfWork 클래스는 그것은에 의해 등록되어
private readonly ISessionFactory _sessionFactory;
private readonly ITransaction _transaction;
public UnitOfWork(ISessionFactory sessionFactory)
{
_sessionFactory = sessionFactory;
CurrentSession = _sessionFactory.OpenSession();
_transaction = CurrentSession.BeginTransaction();
}
다음 생성자가 : 나는 정확히 어떻게하지만 모르는 내뿜어. 이것은 내가 혼란스러워하는 곳입니다. 나는 항상 모든 것이 전부이거나 아무것도 원하지 않는다.
편집 :
여기가 NHibernate에 등록 과정에 대한 모든 코드
public NHibernateRegistry()
{
FluentConfiguration fluentConfig = Fluently.Configure()
.Database(
MsSqlConfiguration.MsSql2008.ShowSql().ConnectionString(x => x.FromConnectionStringWithKey("conn")))
.ProxyFactoryFactory(typeof (ProxyFactoryFactory).AssemblyQualifiedName)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<CustomerMap>());
Configuration configuration = fluentConfig.BuildConfiguration();
ConfigureNhibernateValidator(configuration);
ISessionFactory sessionFactory = fluentConfig.BuildSessionFactory();
For<Configuration>().LifecycleIs(new HybridLifecycle()).Singleton().Use(configuration);
For<ISessionFactory>().LifecycleIs(new HybridLifecycle()).Singleton().Use(sessionFactory);
For<ISession>().LifecycleIs(new HybridLifecycle())
.Use(x => x.GetInstance<ISessionFactory>().OpenSession());
For<IUnitOfWork>().LifecycleIs(new HybridLifecycle())
.Use<UnitOfWork>();
For<ITssPrincipal>().HybridHttpOrThreadLocalScoped().Use(container => BuildUserInstanceFromThreadCurrentPrincipal());
Scan(x =>
{
x.TheCallingAssembly();
x.WithDefaultConventions();
});
}
편집 : 아래의 예에서 DI 문제의 예를 , 당신은 볼 그쪽으로 RepoA는 RepoB와 모두 DI'd한다 StructureMap에서 제공하는 UnitOfWork를 얻습니다.
public RepoA(IUnitOfWork unitOfWork, ITssPrincipal principal,
IRepoB repoB)
{
}
public RepoB(IUnitOfWork unitOfWork, ITssPrincipal principal)
{
}
내가 RepoA의 기능에 새로운 세션을 생성하더라도, repoB는 여전히 원래의 UnitOfWork 세션을 사용하는 것입니다
그것은 그것을 만드는 의존성 주입 컨테이너로 StructureMap를 사용하여 MVC 웹 사이트처럼 보이는
foreach 루프를 수행하는 클래스에서 세션 팩토리를 사용할 수 있습니까? UnitOfWork.CurrentSession을 사용하는 대신 루프를 통해 팩토리를 사용하여 새 세션을 만든 다음 해당 세션에 대해 BeginTransaction()을 호출 할 수 있습니까? – jkriddle
주 세션 설정 방법을 표시하는 코드가 추가되었습니다. 어떻게 든 내 루프에서 fluentConfig.BuildSessionFactory()를 사용할 수 있습니까? – getit
Randy의 답변은 옳았지만 마지막 의견에 추가하십시오. 항상 세션은 저렴하지만 세션 * 공장은 비쌉니다.그러므로 항상 새로운 공장을 만드는 것을 피하십시오 (그리고 결코 필요없는 의존성 주입을 사용하여). – jkriddle