Castle Windsor Nhibernate 多个数据库会话
Castle Windsor Nhibernate multiple database sessions
我正在尝试在我的城堡温莎容器中为 2 个不同的 NHibernate 会话注册多个命名组件,并根据不同的接口(IRepository、IReadOnlyRepository)注入适当的 NHibernate 会话。
我正在使用 AbstractFacility 来注册我的 ISession 和 ISessionFactory:
public class PersistenceFacility : AbstractFacility
{
private const string DBCONNECTFACTORY = "dbconnectfactory";
private const string ODSCONNECTFACTORY = "odsconnectfactory";
private const string DBCONNECT = "dbconnect";
private const string ODSCONNECT = "odsconnect";
protected override void Init()
{
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(CreateDBConnectSessionFactory)
.LifeStyle
.Singleton
.Named(DBCONNECTFACTORY),
Component.For<ISessionFactory>()
.UsingFactoryMethod(CreateODSConnectSessionFactory)
.LifeStyle
.Singleton
.Named(ODSCONNECTFACTORY)
);
Kernel.Register(
//Nhibernate session
Component.For<ISession>()
.UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>(DBCONNECTFACTORY).OpenSession())
.LifeStyle
.PerWebRequest
.Named(DBCONNECT),
Component.For<ISession>()
.UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>(ODSCONNECTFACTORY).OpenSession())
.LifeStyle
.PerWebRequest
.Named(ODSCONNECT)
);
}
private static ISessionFactory CreateDBConnectSessionFactory()
{
return Fluently.Configure()
.Database(NhOracleConfiguration.Dialect.ConnectionString(x => x.FromConnectionStringWithKey("DBConnect")))
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetAssembly(typeof(StudentMapping))))
.BuildSessionFactory();
}
private static ISessionFactory CreateODSConnectSessionFactory()
{
return Fluently.Configure()
.Database(NhOracleConfiguration.Dialect.ConnectionString(x => x.FromConnectionStringWithKey("ODSConnect")))
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetAssembly(typeof(ReadOnlyStudentMapping))))
.BuildSessionFactory();
}
}
以上对于单个 ISession 效果很好,但我现在需要多个,所以这是我的尝试。
我正在按如下方式注册我的存储库:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Kernel.ComponentRegistered += Kernel_ComponentRegistered;
container.AddFacility(new PersistenceFacility());
// Register all controllers
container.Register(
// Unitofwork interceptor
Component.For<NhUnitOfWorkInterceptor>().LifeStyle.PerWebRequest,
// All validators
Classes.FromAssembly(Assembly.GetAssembly(typeof(StudentValidator))).BasedOn(typeof(IValidator<>)).WithService.Base().LifestyleTransient(),
// All repositories
Classes.FromAssembly(Assembly.GetAssembly(typeof(NhStudentRepository)))
.InSameNamespaceAs<NhStudentRepository>()
.WithService.DefaultInterfaces()
.LifestyleTransient(),
// All services
Classes.FromAssembly(Assembly.GetAssembly(typeof(StudentService))).InSameNamespaceAs<StudentService>().WithService.DefaultInterfaces().LifestyleTransient()
);
}
以上代码正在注册所有存储库(IRepository 和 IReadOnlyRepository),因为它们位于同一命名空间中。
如何确保将适当的 ISession 注入到正确的存储库中? (IRepository, IReadOnlyRepository)
我的方法是否朝着正确的方向前进?我当然愿意完全修改我注册组件和依赖项的方式。
我使用以下配置尝试了您的代码;
public class Repository<T>:IRepository<T> where T:class
{
public T GetById(string id)
{
return UnitOfWork.CurrentDBSession.Get<T>(id);
}
}
和
public class UnitOfWork
{
public static ISession CurrentDBSession
{
get
{
var session = IoC.Container.Resolve<ISession>("dbconnect");
return session;
}
}
}
它有效 well.This 如果我正确理解你的问题,可能会对你有所帮助。
我在注册两个不同的存储库时使用 ServiceOverride 解决了这个问题 类(IRepository、IReadOnlyRepository)。
我很想看到更新的解决方案,因为 ServiceOverride 在 Castle Windsor 3.0 之后似乎已被弃用。
我实现的关键是让我的不同存储库位于不同的命名空间中,并让 Castle Windsor 为每个存储库注册一个不同的命名 ISession 组件:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Kernel.ComponentRegistered += Kernel_ComponentRegistered;
container.AddFacility(new PersistenceFacility());
// Register all controllers
container.Register(
// Unitofwork interceptor
Component.For<NhUnitOfWorkInterceptor>().LifeStyle.PerWebRequest,
// All validators
Classes.FromAssembly(Assembly.GetAssembly(typeof(StudentValidator))).BasedOn(typeof(IValidator<>)).WithService.Base().LifestyleTransient(),
// All repositories
Classes.FromAssembly(Assembly.GetAssembly(typeof(NhStudentRepository)))
.InSameNamespaceAs<NhStudentRepository>()
.WithService.DefaultInterfaces()
.Configure(c =>
{
c.DependsOn(
ServiceOverride
.ForKey<ISession>()
.Eq(DBCONNECT)
);
})
.LifestyleTransient(),
// All read only repositories
Classes.FromAssembly(Assembly.GetAssembly(typeof(NhCourseRepository)))
.InSameNamespaceAs<NhCourseRepository>()
.WithService.DefaultInterfaces()
.Configure(c =>
{
c.DependsOn(
ServiceOverride
.ForKey<ISession>()
.Eq(ODSCONNECT)
);
})
.LifestyleTransient(),
// All services
Classes.FromAssembly(Assembly.GetAssembly(typeof(StudentService))).InSameNamespaceAs<StudentService>().WithService.DefaultInterfaces().LifestyleTransient()
);
}
我正在尝试在我的城堡温莎容器中为 2 个不同的 NHibernate 会话注册多个命名组件,并根据不同的接口(IRepository、IReadOnlyRepository)注入适当的 NHibernate 会话。
我正在使用 AbstractFacility 来注册我的 ISession 和 ISessionFactory:
public class PersistenceFacility : AbstractFacility
{
private const string DBCONNECTFACTORY = "dbconnectfactory";
private const string ODSCONNECTFACTORY = "odsconnectfactory";
private const string DBCONNECT = "dbconnect";
private const string ODSCONNECT = "odsconnect";
protected override void Init()
{
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(CreateDBConnectSessionFactory)
.LifeStyle
.Singleton
.Named(DBCONNECTFACTORY),
Component.For<ISessionFactory>()
.UsingFactoryMethod(CreateODSConnectSessionFactory)
.LifeStyle
.Singleton
.Named(ODSCONNECTFACTORY)
);
Kernel.Register(
//Nhibernate session
Component.For<ISession>()
.UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>(DBCONNECTFACTORY).OpenSession())
.LifeStyle
.PerWebRequest
.Named(DBCONNECT),
Component.For<ISession>()
.UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>(ODSCONNECTFACTORY).OpenSession())
.LifeStyle
.PerWebRequest
.Named(ODSCONNECT)
);
}
private static ISessionFactory CreateDBConnectSessionFactory()
{
return Fluently.Configure()
.Database(NhOracleConfiguration.Dialect.ConnectionString(x => x.FromConnectionStringWithKey("DBConnect")))
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetAssembly(typeof(StudentMapping))))
.BuildSessionFactory();
}
private static ISessionFactory CreateODSConnectSessionFactory()
{
return Fluently.Configure()
.Database(NhOracleConfiguration.Dialect.ConnectionString(x => x.FromConnectionStringWithKey("ODSConnect")))
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetAssembly(typeof(ReadOnlyStudentMapping))))
.BuildSessionFactory();
}
}
以上对于单个 ISession 效果很好,但我现在需要多个,所以这是我的尝试。
我正在按如下方式注册我的存储库:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Kernel.ComponentRegistered += Kernel_ComponentRegistered;
container.AddFacility(new PersistenceFacility());
// Register all controllers
container.Register(
// Unitofwork interceptor
Component.For<NhUnitOfWorkInterceptor>().LifeStyle.PerWebRequest,
// All validators
Classes.FromAssembly(Assembly.GetAssembly(typeof(StudentValidator))).BasedOn(typeof(IValidator<>)).WithService.Base().LifestyleTransient(),
// All repositories
Classes.FromAssembly(Assembly.GetAssembly(typeof(NhStudentRepository)))
.InSameNamespaceAs<NhStudentRepository>()
.WithService.DefaultInterfaces()
.LifestyleTransient(),
// All services
Classes.FromAssembly(Assembly.GetAssembly(typeof(StudentService))).InSameNamespaceAs<StudentService>().WithService.DefaultInterfaces().LifestyleTransient()
);
}
以上代码正在注册所有存储库(IRepository 和 IReadOnlyRepository),因为它们位于同一命名空间中。
如何确保将适当的 ISession 注入到正确的存储库中? (IRepository, IReadOnlyRepository)
我的方法是否朝着正确的方向前进?我当然愿意完全修改我注册组件和依赖项的方式。
我使用以下配置尝试了您的代码;
public class Repository<T>:IRepository<T> where T:class
{
public T GetById(string id)
{
return UnitOfWork.CurrentDBSession.Get<T>(id);
}
}
和
public class UnitOfWork
{
public static ISession CurrentDBSession
{
get
{
var session = IoC.Container.Resolve<ISession>("dbconnect");
return session;
}
}
}
它有效 well.This 如果我正确理解你的问题,可能会对你有所帮助。
我在注册两个不同的存储库时使用 ServiceOverride 解决了这个问题 类(IRepository、IReadOnlyRepository)。
我很想看到更新的解决方案,因为 ServiceOverride 在 Castle Windsor 3.0 之后似乎已被弃用。
我实现的关键是让我的不同存储库位于不同的命名空间中,并让 Castle Windsor 为每个存储库注册一个不同的命名 ISession 组件:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Kernel.ComponentRegistered += Kernel_ComponentRegistered;
container.AddFacility(new PersistenceFacility());
// Register all controllers
container.Register(
// Unitofwork interceptor
Component.For<NhUnitOfWorkInterceptor>().LifeStyle.PerWebRequest,
// All validators
Classes.FromAssembly(Assembly.GetAssembly(typeof(StudentValidator))).BasedOn(typeof(IValidator<>)).WithService.Base().LifestyleTransient(),
// All repositories
Classes.FromAssembly(Assembly.GetAssembly(typeof(NhStudentRepository)))
.InSameNamespaceAs<NhStudentRepository>()
.WithService.DefaultInterfaces()
.Configure(c =>
{
c.DependsOn(
ServiceOverride
.ForKey<ISession>()
.Eq(DBCONNECT)
);
})
.LifestyleTransient(),
// All read only repositories
Classes.FromAssembly(Assembly.GetAssembly(typeof(NhCourseRepository)))
.InSameNamespaceAs<NhCourseRepository>()
.WithService.DefaultInterfaces()
.Configure(c =>
{
c.DependsOn(
ServiceOverride
.ForKey<ISession>()
.Eq(ODSCONNECT)
);
})
.LifestyleTransient(),
// All services
Classes.FromAssembly(Assembly.GetAssembly(typeof(StudentService))).InSameNamespaceAs<StudentService>().WithService.DefaultInterfaces().LifestyleTransient()
);
}