Guy
Guy

Reputation: 336

Pass a parameter to a WCF service constructor

I need to pass an exist DI container as a parameter to a WCF service constructor In order to do that i'm using IInstanceProvider The WCF service should be hosted in self host.

public class CustomInstanceProvider : IInstanceProvider, IContractBehavior
{
    private readonly IUnityContainer UnityContainer;

    public CustomInstanceProvider(IUnityContainer unityContainer)
    {
        if (unityContainer == null)
        {
            throw new ArgumentNullException("unityContainer");
        }

        UnityContainer = unityContainer;
    }


    #region Implementation of IInstanceProvider

    public object GetInstance(InstanceContext instanceContext)
    {
        return new Service(UnityContainer);
    }

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

    }

    #endregion

    #region Implementation of IContractBehavior

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {

    }

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

    }

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

    }


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

    }

    #endregion
}

I also implement CustomServiceHost

  public class CustomServiceHost : ServiceHost
    {
        public CustomServiceHost(IUnityContainer unityContainer, Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
        if (unityContainer == null)
        {
            throw new ArgumentNullException("unityContainer is null");
        }

        foreach (var cd in this.ImplementedContracts.Values)
        {
            cd.Behaviors.Add(new CustomInstanceProvider(unityContainer));
        }

    }
}

and ServiceHostFactory

public class CustomServiceHostFactory : ServiceHostFactory
{
    private readonly IUnityContainer UnityContainer;
    public CustomServiceHostFactory(IUnityContainer unityContainer)
    {
        UnityContainer = unityContainer;
    }

    protected override ServiceHost CreateServiceHost(Type serviceType,
        Uri[] baseAddresses)
    {
        return new CustomServiceHost(UnityContainer, serviceType, baseAddresses);
    }

}

I creates WCF Service :

           var uris = new Uri[1];
        uris[0] = new Uri("http://localhost:8793/Service/");
        CustomServiceHostFactory factory = new CustomServiceHostFactory(Container);
        CustomServiceHost serviceHost =  (CustomServiceHost)factory.CreateServiceHost("guy",uris);
        ServiceEndpoint endpoint = serviceHost.AddServiceEndpoint(typeof(IService), new WSHttpBinding(), "");
        serviceHost.Open();

I am getting an exception :

 An exception occurred while initializing module 'PluginsModule'. 

- The exception message was: 'ServiceHostFactory.CreateServiceHost' cannot be invoked within the current hosting environment. This API requires that the calling application be hosted in IIS or WAS.

- The Assembly that the module was trying to be loaded from was:<"PluginsModule.plugin" , Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

Check the InnerException property of the exception for more information. If the exception occurred while creating an object in a DI container, you can exception.GetRootException() to help locate the root cause of the problem.

Please help

thanks.

Upvotes: 1

Views: 8836

Answers (1)

Guy
Guy

Reputation: 336

Ok, The problem was that I don't need to use the CustomInstanceProvider. ServiecInstanceProvider is only for IIS use. I want my service to be hosted in self-host.

        var uris = new Uri[1];
        uris[0] = new Uri("http://localhost:8793//Service/ntService/");
        var serviceHost = new CustomServiceHost(Container,typeof(Service),uris);
        serviceHost.AddDefaultEndpoints();

Thats all I needed to to: Implement IInstanceProvider & ServiceHost. Now I can pass parameter to my constructor.

Thanks

Upvotes: 6

Related Questions