session-per-request implementation for WCF, NHibernate, and Ninject

前端 未结 3 1526
攒了一身酷
攒了一身酷 2021-02-08 02:25

I am trying to implement a session-per-request model in my WCF application, and I have read countless documents on this topic, but looks like there is not a complete demonstrati

3条回答
  •  后悔当初
    2021-02-08 02:58

    Hy

    You can do the following:

    public class DomainModule : NinjectModule
    {
        private const string RealSessionIndicator = "RealSession";
    
        private readonly ProxyGenerator proxyGenerator = new ProxyGenerator();
    
        public override void Load()
        {
            this.Bind().ToMethod(ctx => ctx.Kernel.Get().OpenSession())
                .When(r => r.Parameters.Any(p => p.Name == RealSessionIndicator))
                .InRequestScope();
    
            this.Bind>().ToMethod(ctx => () => ctx.Kernel.Get(new Parameter(RealSessionIndicator, (object)null, true)));
    
            this.Bind()
                .ToMethod(this.CreateSessionProxy)
                .InTransientScope();
    
            this.Bind().ToMethod(ctx => ctx.Kernel.Get().BuildSessionFactory()).InSingletonScope();
        }
    
        private ISession CreateSessionProxy(IContext ctx)
        {
            var session = (ISession)this.proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof(ISession), new[] { typeof(ISessionImplementor) }, ctx.Kernel.Get());
            return session;
        }
    }
    
    public class SessionInterceptor : IInterceptor
    {
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    
        private readonly Func sessionProvider;
    
        public SessionInterceptor(Func sessionProvider)
        {
            this.sessionProvider = sessionProvider;
        }
    
        public void Intercept(IInvocation invocation)
        {
            try
            {
                var session = this.sessionProvider();
                invocation.ReturnValue = invocation.Method.Invoke(session, invocation.Arguments);
            }
            catch (TargetInvocationException exception)
            {
                Log.Error(exception);
                throw;
            }
        }
    }
    

    With that you can use everywhere ISession without caring about the details. You can edit InRequestScope with InScope(ctx => OperationContext.Current) to use WCF scope

提交回复
热议问题