I have the following after doing some research on other questions:
MyServiceHost:
public class MyServiceHost : ServiceHost
{
pub
I´m using the following classes in my windows service to create WCF services and inject dependencies to it using unity.
UnityInstanceProvider:
internal class UnityInstanceProvider : IInstanceProvider {
private readonly IUnityContainer container;
private readonly Type contractType;
public UnityInstanceProvider(IUnityContainer container, Type contractType) {
this.container = container;
this.contractType = contractType;
}
public object GetInstance(InstanceContext instanceContext) {
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message) {
return container.Resolve(contractType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance) {
container.Teardown(instance);
}
}
UnityServiceBehavior:
public class UnityServiceBehavior : IServiceBehavior {
private readonly IUnityContainer container;
public UnityServiceBehavior(IUnityContainer container) {
this.container = container;
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers) {
foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints) {
if (endpointDispatcher.ContractName != "IMetadataExchange") {
string contractName = endpointDispatcher.ContractName;
ServiceEndpoint serviceEndpoint = serviceDescription.Endpoints.FirstOrDefault(e => e.Contract.Name == contractName);
endpointDispatcher.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(this.container, serviceEndpoint.Contract.ContractType);
}
}
}
}
}
UnityServiceHost:
public class UnityServiceHost : ServiceHost {
private IUnityContainer unityContainer;
public UnityServiceHost(IUnityContainer unityContainer, Type serviceType)
: base(serviceType) {
this.unityContainer = unityContainer;
}
protected override void OnOpening() {
base.OnOpening();
if (this.Description.Behaviors.Find<UnityServiceBehavior>() == null) {
this.Description.Behaviors.Add(new UnityServiceBehavior(this.unityContainer));
}
}
}
With this classes you can do the following (The configuration of services is done in .config):
UnityContainer container = new UnityContainer();
UnityServiceHost serviceHost = new UnityServiceHost(container, typeof("Type of Service to host"));
serviceHost.Open();
The CreateServiceHost method expects an array of Uri
instances, so try this instead:
ServiceHost host = shf.CreateServiceHost(serviceType, new[] { serviceUri });
You can map interfaces to types in either XML or code, but I'd recommend code, since XML has too high a maintenance overhead.
The Main
method is an excellent Composition Root, but if you want to configure the container at that level, you'll need to pass it from the Main
method to MyServiceHostFactory
- which is perfectly fine when you host the service in a console application, but will not work if you want to host it in IIS, where MyServiceHostFactory
should be the Composition Root, since IIS requires a default constructor.
ServiceHostFactory
is for hosting in IIS. In self hosting you should use your derived ServiceHost
directly. Here you have whole example including Unity configuration.