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

前端 未结 3 1513
攒了一身酷
攒了一身酷 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:45

    I have implemented per request session lifetime with the help of IDispatchMessageInspector. Probably you could implement custom lifetime manager for Ninject to achieve per web request.

    0 讨论(0)
  • 2021-02-08 02:57

    You may be able to do it by using the extension points provided in the IInstanceContextProvider Interface.

    0 讨论(0)
  • 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<ISession>().ToMethod(ctx => ctx.Kernel.Get<ISessionFactory>().OpenSession())
                .When(r => r.Parameters.Any(p => p.Name == RealSessionIndicator))
                .InRequestScope();
    
            this.Bind<Func<ISession>>().ToMethod(ctx => () => ctx.Kernel.Get<ISession>(new Parameter(RealSessionIndicator, (object)null, true)));
    
            this.Bind<ISession>()
                .ToMethod(this.CreateSessionProxy)
                .InTransientScope();
    
            this.Bind<ISessionFactory>().ToMethod(ctx => ctx.Kernel.Get<Configuration>().BuildSessionFactory()).InSingletonScope();
        }
    
        private ISession CreateSessionProxy(IContext ctx)
        {
            var session = (ISession)this.proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof(ISession), new[] { typeof(ISessionImplementor) }, ctx.Kernel.Get<SessionInterceptor>());
            return session;
        }
    }
    
    public class SessionInterceptor : IInterceptor
    {
        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    
        private readonly Func<ISession> sessionProvider;
    
        public SessionInterceptor(Func<ISession> 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

    0 讨论(0)
提交回复
热议问题