Nov*_*ice 7 nhibernate wcf nhibernate-3
所以我的猜测是:
Hibernate使用WCF进行会话管理的任何建议(最佳实践)?
任何人都知道
WcfOperationSessionContext(hibernate 3.0)类?
how to use it with WCF?
Run Code Online (Sandbox Code Playgroud)
好吧,使它具体化:
假设我有一个名为DataServices的 WCF服务
class WCFDataService .....
{
void SaveMyEntity(MyEntity entity)
{
.....................?? // How to do? Best Way
// Should i take one session and use it all times
// Should i take session and dipsose when operation finished then get
//new session for new operations?
// If many clients call my WCF service function at the same time?
// what may go wrong?
// etc....
}
}
Run Code Online (Sandbox Code Playgroud)
我需要一个NHibernateServiceProvider类
class NHibernateServiceProvider ....
{
// How to get Session ?? Best way
ISession GetCurrentSession(){.... }
DisposeSession(){ ....}
}
Run Code Online (Sandbox Code Playgroud)
最好的祝愿
PS:我在这里和其他网页上都读过类似的条目.但看不出"具体"的答案.
WcfOperationSessionContext类似于ThreadStaticSessionContext和WebRequestSessionContext,是会话上下文的实现.会话上下文用于将ISession实例绑定(关联)到特定上下文.
可以通过调用ISessionFactory.GetCurrentSession()来检索当前上下文中的会话.
你可以找到更多的信息在这里会话环境.
WcfOperationSessionContext表示跨越WCF操作的整个持续时间的上下文.您仍然需要在操作开始时处理会话的绑定,并在操作结束时处理会话的解除绑定/提交/处理.
要访问wcf管道中的开始/结束操作,您需要实现IDispatchMessageInspector.你可以在这里看到一个样本.
另外关于WCF集成:如果你使用ThreadStatic会话上下文它似乎可以在开发上工作,但是当wcf管道中的各种组件(例如:授权,身份验证)在不同的线程上执行时,你将在生产中遇到问题.
至于你几乎把它钉在最佳实践上:使用WcfOperationSessionContext存储当前会话和IDispatchMessageInspector来开始/完成你的工作单元.
编辑 - 解决您添加的详细信息:如果您按照上面的说明配置了WcfOperationSessionContext并执行绑定/解除绑定,您只需将ISessionFactory注入您的服务并使用factory.GetCurrentSession().如果时间允许,我会发布一个样本prj.
这是示例项目
我们用于管理与WCF的NHibernate会话的模型如下:
1)我们有自己的ServiceHost类,它继承自System.ServiceModel.ServiceHost,它也实现了ICallContextInitializer.我们将服务主机实例添加到服务中的每个操作,如下所示:
protected override void InitializeRuntime()
{
base.InitializeRuntime();
foreach (ChannelDispatcher cd in this.ChannelDispatchers)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
foreach (DispatchOperation op in ed.DispatchRuntime.Operations)
{
op.CallContextInitializers.Add(this);
}
}
}
}
public void AfterInvoke(object correlationState)
{
// We don't do anything after the invoke
}
public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
{
OperationContext.Current.Extensions.Add(new SessionOperationContext());
return null;
}
Run Code Online (Sandbox Code Playgroud)
BeforeInvoke只是确保每个WCF调用的OperationContext都有自己的会话.我们发现IDispatchMessageInspector存在问题,其中会话在响应序列化期间不可用 - 如果使用延迟加载则会出现问题.
2)然后我们的SessionOperationContext将被调用以附加自身,我们使用OperationCompleted事件来移除自己.这样我们就可以确保会话可用于响应序列化.
public class SessionOperationContext : IExtension<OperationContext>
{
public ISession Session { get; private set; }
public static SessionOperationContext Current
{
get
{
OperationContext oc = OperationContext.Current;
if (oc == null) throw new InvalidOperationException("Must be in an operation context.");
return oc.Extensions.Find<SessionOperationContext>();
}
}
public void Attach(OperationContext owner)
{
// Create the session and do anything else you required
this.Session = ... // Whatever instantiation method you use
// Hook into the OperationCompleted event which will be raised
// after the operation has completed and the response serialised.
owner.OperationCompleted += new EventHandler(OperationCompleted);
}
void OperationCompleted(object sender, EventArgs e)
{
// Tell WCF this extension is done
((OperationContext)sender).Extensions.Remove(this);
}
public void Detach(OperationContext owner)
{
// Close our session, do any cleanup, even auto commit
// transactions if required.
this.Session.Dispose();
this.Session = null;
}
}
Run Code Online (Sandbox Code Playgroud)
我们已经在高负载应用程序中成功使用了上述模式,它似乎运行良好.
总而言之,这类似于新的WcfOperationSessionContext所做的事情(当我们发现上面的模式时它不存在;-))但也克服了延迟加载的问题.
关于提出的其他问题:如果您使用上述模型,您只需执行以下操作:
void SaveMyEntity(MyEntity entity)
{
SessionOperationContext.Current.Session.Save(entity);
}
Run Code Online (Sandbox Code Playgroud)
您可以保证会话始终存在,并且一旦WCF操作完成,它将被丢弃.如果需要,您可以以正常方式使用交易.
| 归档时间: |
|
| 查看次数: |
5624 次 |
| 最近记录: |