web-dev-qa-db-fra.com

Le service WCF peut-il avoir des constructeurs?

Lorsque je crée un service WCF dans ma solution, puis-je faire ce qui suit, avoir un constructeur avec un paramètre à transmettre? Si oui, comment, quand et où le runtime remplit-il mon objet IBusinessLogic requis?

[ServiceContract]
public interface IServiceContract
{
    [OperationContract]
    ...
}

public class MyService : IServiceContract
{
    IBusinessLogic _businessLogic;
    public ServiceLayer(IBusinessLogic businessLogic)
    {
        _businessLogic = businessLogic;
    }
    ...
}
41
Ray

Par défaut, WCF n'utilisera que le constructeur par défaut, vous ne pouvez pas utiliser de constructeurs paramétrés. Vous devez faire un peu de travail supplémentaire pour créer des constructeurs paramétrés d'appel WCF.

Vous pouvez essayer ceci:

Comment passer des valeurs au constructeur sur mon service wcf?

13
Kev

Vous pouvez demander à WCF d'appeler (en quelque sorte indirectement) des constructeurs non par défaut, pour que cela fonctionne, vous devez rouler votre propre fournisseur d'instance. Vous devez implémenter IInstanceProvider et ajouter un comportement de service personnalisé. Quelques liens qui vous montreront comment procéder en combinaison avec Spring.NET:

Injection de dépendance de service WCF

Exemple de code WCF Service Dependency Injection

6
Raymond Roestenburg
6
Mark Cidade

Un autre cas, en plus des autres réponses, est lors de la création d'un service singleton - c'est lorsque vous passez une instance de votre service au ServiceHost (par opposition à un type);

Évidemment, lorsque vous créez l'instance, vous pouvez utiliser n'importe quel constructeur;

Cette approche nécessitera l'ajout d'un attribut à votre service: [ServiceBehavior (InstanceContextMode.Single)];

4
Yossi Dahan

J'ai paraphrasé la solution de @Mark Seemann comme comportement du fournisseur d'instance générique.

Comment l'utiliser:

var Host = new ServiceHost(typeof(MyService), baseAddress);
var instanceProvider = new InstanceProviderBehavior<T>(() => new MyService(businessLogic));
instanceProvider.AddToAllContracts(Host);

Code InstanceProviderBehavior:

public class InstanceProviderBehavior<T> : IInstanceProvider, IContractBehavior
    where T : class
{
  private readonly Func<T> m_instanceProvider;

  public InstanceProviderBehavior(Func<T> instanceProvider)
  {
    m_instanceProvider = instanceProvider;
  }

  // I think this method is more suitable to be an extension method of ServiceHost.
  // I put it here in order to simplify the code.
  public void AddToAllContracts(ServiceHost serviceHost)
  {
    foreach (var endpoint in serviceHost.Description.Endpoints)
    {
      endpoint.Contract.Behaviors.Add(this);
    }
  }

  #region IInstanceProvider Members

  public object GetInstance(InstanceContext instanceContext, Message message)
  {
    return this.GetInstance(instanceContext);
  }

  public object GetInstance(InstanceContext instanceContext)
  {
    // Create a new instance of T
    return m_instanceProvider.Invoke();
  }

  public void ReleaseInstance(InstanceContext instanceContext, object instance)
  {
    try
    {
      var disposable = instance as IDisposable;
      if (disposable != null)
      {
        disposable.Dispose();
      }
    }
    catch { }
  }

  #endregion

  #region IContractBehavior Members

  public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
  {
  }

  public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
  {
  }

  public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
  {
    dispatchRuntime.InstanceProvider = this;
  }

  public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
  {
  }

  #endregion
}
4
HuBeZa

Vous devez implémenter IInstanceProvider pour pouvoir appeler un constructeur de service paramétré. De ce constructeur ne sera pas disponible dans le proxy généré.

2
Haripraghash