我正在尝试在我的城堡windsor容器中为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)
我的方法是否正朝着正确的方向前进?我当然愿意完全改变我注册组件和依赖项的方式。
答案 0 :(得分:2)
我使用以下配置尝试了您的代码;
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;
}
}
}
它运作良好。如果我理解你的问题,这可能对你有所帮助。
答案 1 :(得分:1)
我在注册两个不同的存储库类(IRepository,IReadOnlyRepository)时使用ServiceOverride解决了这个问题。
我很想看到更新的解决方案,因为在Castle Windsor 3.0之后,ServiceOverride似乎已被弃用。
我的实现的关键是让我的不同存储库存在于不同的命名空间中,让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()
);
}