Ray
Ray

Reputation: 12441

Can WCF Service have constructors?

When I new a WCF service in my solution, can I do the following, have a constructor with parameter to pass in? If yes, how, when and where does the runtime fill in my required IBusinessLogic object?

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

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

Upvotes: 42

Views: 45700

Answers (6)

HuBeZa
HuBeZa

Reputation: 4761

I paraphrased @Mark Seemann's solution as a generic instance provider behavior.

How to use it:

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

InstanceProviderBehavior code:

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
}

Upvotes: 4

Yossi Dahan
Yossi Dahan

Reputation: 5357

Another case, in addition to the other responses, is when creating singleton service - this is when you pass an instance of your service to the ServiceHost (as opposed to a type);

Obviously as you create the instance you can use whichever constructor;

This approach will require adding an attribute to your service: [ServiceBehavior(InstanceContextMode.Single)];

Upvotes: 4

Kev
Kev

Reputation: 119806

Out of the box WCF will only use the default constructor, you can't use parameterised constructors. You have to do a bit of extra work to make WCF call parameterised constructors.

You could try this:

How do I pass values to the constructor on my wcf service?

Upvotes: 13

Haripraghash
Haripraghash

Reputation:

You have to implement IInstanceProvider to be able to call a parametrized service constructor. Of this constructor will not be available in the generated proxy.

Upvotes: 2

Raymond Roestenburg
Raymond Roestenburg

Reputation: 4890

You can get WCF to (sort of indirectly) call non default constructors, for that to work you need to roll your own instance provider. You would need to implement IInstanceProvider and add a custom Service Behavior. Some links that will show you how to do this in combination with Spring.NET:

WCF Service Dependency Injection

Code example WCF Service Dependency Injection

Upvotes: 6

Mark Cidade
Mark Cidade

Reputation: 99957

Look at ServiceHostFactory.

Upvotes: 6

Related Questions