我正在尝试第一次在 Wcf 服务中使用 Windsor NHibernate Facility 并替换当前手动注册 NHibernate,以便可以在所有服务中使用一致的方法。
目前的工作方法
以前我一直在手动注册 NHibernate 组件。
container.Register(
Component.For<ISessionFactory>().UsingFactoryMethod(() => CreateMappings("SomeConnectionString").BuildSessionFactory()));
container.Register(
Component.For<ISession>().LifeStyle.PerWcfOperation().UsingFactoryMethod(OpenSession));
然后,我使用自定义服务行为为每个操作创建和完成事务范围。
public class TransactionBehavior : IServiceBehavior
{
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (var cdb in serviceHostBase.ChannelDispatchers)
{
var channelDispatcher = cdb as ChannelDispatcher;
if (null == channelDispatcher) continue;
foreach (var endpointDispatcher in channelDispatcher.Endpoints)
{
foreach (var dispatchOperation in endpointDispatcher.DispatchRuntime.Operations)
{
dispatchOperation.CallContextInitializers.Add(new TransactionContext());
}
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { }
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { }
}
public class TransactionContext : ICallContextInitializer
{
private TransactionScope transaction;
public Object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
{
transaction = new TransactionScope();
return null;
}
public void AfterInvoke(Object correlationState)
{
if(transaction != null)
{
transaction.Complete();
transaction.Dispose();
}
}
}
NHibernate 设施的集成
我已经下载了0.3.1.2001 工件并使用下面的资源尝试插入该工具并移除任何手动连接到 NHibernate 的线路。但是我不想用Transactional
andTransaction
属性来装饰服务和方法。以下是我目前的线材。
container.Register(Component.For<INHibernateInstaller>().ImplementedBy<MyNHibernateInstaller>();
container.AddFacility<AutoTxFacility>();
container.AddFacility<NHibernateFacility>();
public class MyNHibernateInstaller : INHibernateInstaller
{
public Maybe<IInterceptor> Interceptor { get { return Maybe.None<IInterceptor>(); } }
public bool IsDefault { get { return true; } }
public string SessionFactoryKey { get { return "sf.default"; } }
public FluentConfiguration BuildFluent()
{
return Fluently
.Configure()
.Database(MsSqlConfiguration
.MsSql2005.ConnectionString("SomeConnectionString") )
.Mappings( m => m.FluentMappings
.AddFromAssemblyOf<TypeFromEntityAssembly>() );
}
public void Registered(ISessionFactory factory)
{
}
}
每当我调用服务端点之一时,服务都会失败,并出现以下异常:
尝试为解析类型“Juice.iCheque.eMoneySystem.Settlement.ISettlementService”实例化模型“NHibernate.ISession”时,上下文中没有事务。如果您已验证您的调用堆栈包含具有 [Transaction] 属性的方法,那么还要确保您已注册 AutoTx Facility。
问题是我如何在NHibernateFacility
我当前的实现中使用而不使用Transaction
属性。
资源
http://richarddingwall.name/2010/08/17/one-nhibernate-session-per-wcf-operation-the-easy-way/
https://github.com/haf/Castle.Facilities.NHibernate/wiki/NHibernate-Facility---快速入门