WCF в IIS: передача данных из ServiceHostFactory в экземпляры Service - PullRequest
1 голос
/ 10 ноября 2010

У меня есть приложение WCF, размещенное на IIS. Я инициализирую контейнер IoC в пользовательском ServiceHostFactory.

По сути, я хотел бы иметь возможность «внедрить» этот контейнер IoC в каждый экземпляр службы, созданный в рамках этого ServiceHost.

Как бы вы этого достигли?

Ariel

1 Ответ

2 голосов
/ 10 ноября 2010

Как вы сказали, вам понадобится пользовательский ServiceHostFactory, который следует использовать для создания ваших сервисов.Примерно так:

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

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

Вам также понадобится ServiceHost, отвечающий за создание необходимой службы:

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();
    }

}

С пользовательской реализацией IServiceBehavior, которая сможет предоставлять провайдеру используемый InstanceProviderдля создания экземпляров службы:

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)
    {
    }

}

И, наконец, поставщик экземпляра, который позволит вам использовать IoC для ввода чего-либо в запрашиваемый экземпляр службы:

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)
    {

    }
}

Надеюсь, что этопомогает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...