Alternativa ao HTTPContext Ao usar o Ninject com um serviço WCF hospedado foi usar a ligação ao MSMQ

StackOverflow https://stackoverflow.com/questions/2046704

  •  20-09-2019
  •  | 
  •  

Pergunta

Eu tenho um serviço WCF de ida, usando a ligação MSMQ que é ativada usando o Serviço de Ativação do Windows no IIS 7.0.

Eu sou um grande fã no Ninject, por isso tenho usado a extensão Ninject para o WCF, que para um serviço típico do HTTP WCF funcionaria muito bem.

No entanto, nos serviços de ativação, não há pipeline HTTP, por isso não posso usar o InRequestScope ao vincular meus tipos porque o System.Web.httpContext.Current é nulo. Estou lutando para encontrar uma alternativa quando o uso foi que me dará o que eu quero. O atributo de modo de aspcompatibilidade também não funciona nesse modo.

Eu pensei que o INTHREADSCOPE poderia funcionar, mas o serviço é criado em um encadeamento separado do que o que é executado.

Então, basicamente, eu preciso do equivalente do HTTPContext para o WCF+era escopo meus objetos no nível de solicitação. Existe algum objeto estático neste mundo que funcionaria da mesma maneira ou mais alguém tem alguma idéia sobre algo que eu possa hackear?

Foi útil?

Solução

Eu implementei minhas próprias extensões WCF para o Ninject 2.0 antes de saber que havia um isto no Github. Minha implementação difere um pouco, mas eu criei uma solução para o escopo de objetos:

using System;
using Ninject.Activation;

namespace Ninject.Contrib.Wcf {
  /// <summary>
  /// Defines Scope Callbacks for WCF Context.
  /// </summary>
  public class NinjectWcfScopeCallbacks {
    /// <summary>
    /// Defines WCF Context scope.
    /// </summary>
    public static readonly Func<IContext, object> WcfContext =
      ctx => (System.ServiceModel.OperationContext.Current != null
                ? System.ServiceModel.OperationContext.Current.
                    InstanceContext.
                    Extensions.Find<NinjectInstanceContext>()
                : null);

    /// <summary>
    /// Defines WCF Web Context scope.
    /// </summary>
    public static readonly Func<IContext, object> WcfWebContext = 
               ctx => System.ServiceModel.Web.WebOperationContext.Current;
  }
}

Para completar, é assim que eu uso o retorno de chamada definido acima:

Bind<IHelloWorldService>()
        .To<HelloWorldService>()
        .InScope(NinjectWcfScopeCallbacks.WcfWebContext);

Os não hospedaram os serviços da WCF, então não tenho certeza se você usaria o WcfWebContext ou WcfContext definido acima, mas você pode tentar e ver. Se WebOperationContext Funciona, então você está pronto. Caso contrário, achei que as coisas são um pouco mais complicadas. Você notará que o trecho de código acima usa um NinjectInstanceContext classe que é anexada ao OperationContext. Esta é uma classe que escrevi que usa mecanismo de "cache e coleta" do Ninject 2.0 que permite que os objetos sejam descartados deterministicamente. Basicamente, a classe é implementos IExtension<InstanceContext> que é um construto WCF para anexar quase tudo ao OperationContext. Esta classe também implementa o Ninject's INotifyWhenDisposed interface que é o que fornece suporte para o descarte determinístico. Aqui está como é a definição de classe:

  /// <summary>
  /// Defines a custom WCF InstanceContext extension that resolves service instances
  /// using Ninject.  
  /// <remarks>
  /// The custom InstanceContext extension provides support for deterministic disposal
  /// of injected dependencies and service instances themselves by being hook into 
  /// Ninject's "cache and collect" mechanism (new in Ninject 2.0) for object life cycle 
  /// management.  This allows binding object instances to the lifetime of a WCF context
  /// and having them deterministically deactivated and disposed.
  /// </remarks>
  /// </summary>
  public class NinjectInstanceContext : 
                IExtension<InstanceContext>, INotifyWhenDisposed {
  }

O restante da minha extensão do WCF para o Ninject é o mesmo que o 1 no github. O que basicamente acontece é que um provedor de instância é criado que está conectado à cadeia "ativação" do WCF - não estou usando a terminologia específica, como entendo as coisas. Portanto, a idéia é que o seu provedor de instância deve fornecer instâncias da classe de serviço do WCF solicitada. Então, é aqui que usamos o Ninject para produzir a instância de serviço. Ao fazer isso, também podemos ativar e injetar quaisquer dependências. O que o provedor de instância faz na minha implementação é encerrar o kernel Ninject em uma instância se NinjectInstanceContext e anexe -o ao OperationContext. A criação do serviço é então delegada a esta extensão do WCF. Quando o provedor da instância é instruído a lançar um serviço, o NinjectInstanceContext que foi anexado ao OperationContext é disposto que, por meio de implementação INotifyWhenDisposed causa o descarte determinístico do serviço (e potencialmente suas dependências).

Espero que essa discussão ajude. Vou ver se consigo obter um código mais concreto postado aqui se você estiver interessado.

Outras dicas

Tenho certeza OperationContext é o que você está procurando

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top