2011-02-01 12 views
11

WCF uygulamamda istek başına bir oturum açma modeli uygulamaya çalışıyorum ve bu konuda sayısız belgeyi okudum, ancak bir bunun tam bir gösterimi. Aslında böyle bu bir olarak bazı çok yararlı makaleler rastladım:istek başına uygulama

NHibernate's ISession, scoped for a single WCF-call

ancak bu NHibernate ve Ninject WCF özel uygulamalar yoktu eski günlerden hepsi, bu yüzden ben uygulayarak ne gerek elde onların özel servis sağlayıcılar, vs. Artık hem Ninject hem de NHibernate, WCF desteğine sahip olduklarından, modüllerini kullanarak işleri tutarlı tutmak isterim, fakat ben burada sona erdi ...

Temel kurulum ve akış aşağıdaki gibi olmalıdır:

  1. Set isteği başlamak veya herhangi bir yerde init zamanda etrafında, açık oturum ve
  2. Depoları SessionFactory.GetCurrentSession kullanarak geçerli oturum örneğini almak geçerli bağlama bağlamak, hizmet başlangıcında
  3. nhibernate konfigürasyonda WcfOperationSessionContext için CurrentSessionContext() yöntem
  4. unbind ve benim bağlamaları işlemek için wcf yaşam döngüsü için erişmek mümkün olmadığını ömrü

benim ilk sorun oldu sonunda yakın bir seans. Ninject koduna bir miktar kazandıktan sonra, yöntemlerimi çok fazla değişmeden ServiceHost'un Açılış/Kapanış olaylarına çınlamayı başardım, ancak sonra Thread-static olduğundan OperationContext'e erişemedim.

Daha sonra asp.net uyumluluğunu etkinleştirmeyi denedim ve Application_BeginRequest ve Application_EndRequest öğelerini kullanmayı denedim ve çok umut verici görünüyordu, ama bunun en iyi çözüm olduğunu düşünmüyorum çünkü http hizmetinden ziyade, hizmet örneğine bağlamam gerekir .

Ninject'in yerleşik wcf uzantı kütüphanelerini kullanarak bunu hiç kimse başardı mı? Ya da yanlış yaptığım şeyler hakkında bir fikrin var mı?

cevap

2

IDispatchMessageInspector yardımı ile istek oturumu ömrü başına uygulamam var. Muhtemelen web isteği başına ulaşmak için Ninject için özel ömür boyu yöneticisi uygulayabilirsiniz.

+0

kullanmak için InSqucope ile InRequestScope'u düzenleyebilirsiniz (ctx => OperationContext.Current). Ben IDispatchMessageInspector okuyordum ve bu uygulama bulundu: Bazı küçük tweaks ile https://igloocoder.net:8443/svn/IglooCommons/trunk/src/IglooCoder.Commons/WcfNhibernate/ , bunu yapmak başardı iş. – salimaabey

+0

Link, maalesef, ne yazık ki bozuldu. :( – Cornelius

1

Hy

Aşağıdaki yapabilirsiniz: aldığımızda

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; 
     } 
    } 
} 

Eğer detayları hakkında önemsemeden her yerde ISession kullanabilirsiniz. WCF alanını

İlgili konular