Reputation: 336
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
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