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)
{
}
}
サービス エンドポイントの 1 つを呼び出すたびに、サービスは次の例外で失敗します。
解決タイプ「Juice.iCheque.eMoneySystem.Settlement.ISettlementService」のモデル「NHibernate.ISession」をインスタンス化しようとすると、コンテキストにトランザクションがありません。コール スタックに [Transaction] 属性を持つメソッドが含まれていることを確認した場合は、AutoTx 機能が登録されていることも確認してください。
問題はNHibernateFacility
、現在の実装で を使用し、Transaction
属性を使用しない方法です。
資力
http://richarddingwall.name/2010/08/17/one-nhibernate-session-per-wcf-operation-the-easy-way/
https://github.com/haf/Castle.Facility.NHibernate/wiki/NHibernate-Facility---クイックスタート