Using Unity Dependency Injection with WCF services

前端 未结 3 1137
醉酒成梦
醉酒成梦 2020-12-15 09:06

I have the following after doing some research on other questions:

MyServiceHost:

public class MyServiceHost : ServiceHost
{
    pub         


        
相关标签:
3条回答
  • 2020-12-15 09:26

    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();
    
    0 讨论(0)
  • 2020-12-15 09:30

    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.

    0 讨论(0)
  • 2020-12-15 09:51

    ServiceHostFactory is for hosting in IIS. In self hosting you should use your derived ServiceHost directly. Here you have whole example including Unity configuration.

    0 讨论(0)
提交回复
热议问题