开发者

WCF on IIS: Passing data from a ServiceHostFactory to the Service instances

开发者 https://www.devze.com 2023-01-24 14:37 出处:网络
I am having a WCF application hosted on IIS. I am initializing an IoC 开发者_运维技巧container in a custom ServiceHostFactory.

I am having a WCF application hosted on IIS. I am initializing an IoC 开发者_运维技巧container in a custom ServiceHostFactory.

Basically what I would like is to be able to "inject" that IoC Container to each Service instance created within the scope of that ServiceHost.

How would you accomplish that?

Ariel


Like you said you will need a custom ServiceHostFactory that should be used in order to create your services. Something like this:

public class SessionPerCallServiceHostFactory : ServiceHostFactory
{
    public SessionPerCallServiceHostFactory()
    {
    }

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

You will also need a ServiceHost responsible for creating the necessary service:

public class SessionPerCallServiceHost : ServiceHost
{
    public SessionPerCallServiceHost()
    {
    }

    public SessionPerCallServiceHost(Type serviceType, params Uri[] baseAddresses)
    : base(serviceType, baseAddresses)
    {
    }

    protected override void OnOpening()
    {
        Description.Behaviors.Add(new SessionPerCallServiceBehavior());
        base.OnOpening();
    }

}

With a custom implementation of IServiceBehavior that will be able to provider the InstanceProvider used to create the service instances:

public class SessionPerCallServiceBehavior : IServiceBehavior
{
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {            
        foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
        {
            ChannelDispatcher cd = cdb as ChannelDispatcher;
            if (cd != null)
            {
                foreach (EndpointDispatcher ed in cd.Endpoints)
                {                        
                    ed.DispatchRuntime.InstanceProvider =
                        new SessionPerCallInstanceProvider(serviceDescription.ServiceType);
                }
            }
        }
    }

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters)
    {
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }

}

And finally the instance provider that will allow you to use the IoC to inject whatever you want in the requested service instance:

public class SessionPerCallInstanceProvider : IInstanceProvider
{
    private readonly Type _serviceType;

    public SessionPerCallInstanceProvider(Type serviceType)
    {
        _serviceType = serviceType;
    }

    public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
    {
        //I'm creating it without any tricks but you could use your IoC container here
        return Activator.CreateInstance(_serviceType);
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        return GetInstance(instanceContext, null);
    }

    public void ReleaseInstance(System.ServiceModel.InstanceContext instanceContext, object instance)
    {

    }
}

Hope it helps!

0

精彩评论

暂无评论...
验证码 换一张
取 消