나는 스스로 해결책을 제시하는 동안이 질문을 던질 것이라고 생각했다.NHibernate와 Autofac으로 여러 데이터베이스 관리하기
대량의 응용 프로그램을 구축 한 후에 추가 데이터베이스 (2 개는 총망라 가능)에 대한 읽기/쓰기를 지원하는 마지막 요구 사항이 있습니다. DI/IoC 구성 요소를 공급하는 Autofac과 함께 NHibernate를 사용하여 애플리케이션을 구축했습니다. FWIW, 이것은 ASP.NET MVC 2 응용 프로그램에 있습니다.
NHibernate 세션을 사용하는 일반 저장소 클래스가 있습니다. 이론적으로 두 번째 데이터베이스에이 일반 저장소 (IRepository<>
)를 계속 사용할 수 있습니다.이 세션에 전달 된 세션이 적절한 SessionFactory에서 생성 된 것이라면 맞습니까?
글쎄, 앱이 시작될 때 Autofac이하는 일을합니다. 세션과의 SessionFactory에 관해서, 나는 상태 모듈이 있습니다
builder.Register(c => c.Resolve<ISessionFactory>().OpenSession())
.InstancePerMatchingLifetimeScope(WebLifetime.Request)
.OnActivated(e =>
{
e.Context.Resolve<TransactionManager>().CurrentTransaction = ((ISession)e.Instance).BeginTransaction();
});
builder.Register(c => ConfigureNHibernate())
.SingleInstance();
기본 SessionFactory를 반환 ConfigureNHibernate은()처럼 보인다
: 현재
private ISessionFactory ConfigureNHibernate()
{
Configuration cfg = new Configuration().Configure();
cfg.AddAssembly(typeof(Entity).Assembly);
return cfg.Configure().BuildSessionFactory();
}
, 이것은 단지로 제한 하나의 데이터베이스. 다른 NHib 시나리오에서, 나는 분리 된 SessionFactory의 인스턴스를 해쉬로 갈아서 필요할 때마다 검색 할 것이다. 우리가 메이저 릴리스에 상당히 가까워 질 때 모든 것을 다시 설계해야하는 것을 원하지 않습니다. 따라서 적어도 두 개의 SessionFactories를 독립적으로 구성 할 수 있도록 위의 메소드를 수정해야한다고 생각합니다. 내 회색 영역은 올바른 저장소가 특정 저장소와 함께 사용되도록 지정하는 방법 (또는 적어도 두 번째 데이터베이스에 특정한 엔터티)을 지정하는 방법입니다.
이런 식으로 IoC 컨테이너와 NHibernate를 사용하는 동안 누구나이 시나리오를 경험 한 적이 있습니까?
내가 구성 파일 경로를 취하는 GetSessionFactory 방법을 스텁 한 편집은 HttpRuntime.Cache에서 일치하는 SessionFactory에의 실존에 대한 검사는,이 아직 존재하지 않는 경우 새로운 인스턴스를 생성하고, 해당 SessionFactory를 반환합니다. 이제는 적절한 설정 경로를 지정하는 방법과시기를 Autofac에 알려주는 방법을 알아야합니다. (빌리의 2006 포스트 here에서 많이 차용)와 같은 새로운 방법은 같습니다 당신이 각 데이터베이스에 갈 엔티티의 다른 유형을 원하는 있으리라 믿고있어
private ISessionFactory GetSessionFactory(string sessionFactoryConfigPath)
{
Configuration cfg = null;
var sessionFactory = (ISessionFactory)HttpRuntime.Cache.Get(sessionFactoryConfigPath);
if (sessionFactory == null)
{
if (!File.Exists(sessionFactoryConfigPath))
throw new FileNotFoundException("The nhibernate configuration file at '" + sessionFactoryConfigPath + "' could not be found.");
cfg = new Configuration().Configure(sessionFactoryConfigPath);
sessionFactory = cfg.BuildSessionFactory();
if (sessionFactory == null)
{
throw new Exception("cfg.BuildSessionFactory() returned null.");
}
HttpRuntime.Cache.Add(sessionFactoryConfigPath, sessionFactory, null, DateTime.Now.AddDays(7), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null);
}
return sessionFactory;
}
캐시에 세션 팩토리를 저장하는 것은 좋지 않습니다. 그것은 단지 사라지고 재창조 될 수있는 것이 아닙니다. –
알아. 실제로는 캐시 된 객체의 수명을 관리해야합니다. Billy의 예제는 실제로이 단계를 더 진행하고 캐싱 관련 사항을 처리하는 Singleton 범위의 SessionManager 클래스를 만들었습니다. 나는 그것을 결국 바보 취급하려고 했으므로 Autofac이 자체 (매우 우아한) 범위 지정 메커니즘을 통해 관리 할 수있게 할 수있었습니다. – nkirkes