Как я передаю значения конструктору на моем wcf сервисе?

Я хотел бы передать значения в конструктора на классе, который реализует мой сервис.

Однако ServiceHost только позволяет мне передать от имени типа для создания, не что аргументы передать его contrstructor.

Я хотел бы смочь передать на фабрике, которая создает мой объект службы.

Что я нашел до сих пор:

102
задан Elias Platek 31 August 2012 в 12:26
поделиться

2 ответа

Вам нужно будет реализовать комбинацию пользовательских ServiceHostFactory , ServiceHost и IInstanceProvider .

Для службы с этой сигнатурой конструктора:

public MyService(IDependency dep)

Вот пример, который может развернуть MyService:

public class MyServiceHostFactory : ServiceHostFactory
{
    private readonly IDependency dep;

    public MyServiceHostFactory()
    {
        this.dep = new MyClass();
    }

    protected override ServiceHost CreateServiceHost(Type serviceType,
        Uri[] baseAddresses)
    {
        return new MyServiceHost(this.dep, serviceType, baseAddresses);
    }
}

public class MyServiceHost : ServiceHost
{
    public MyServiceHost(IDependency dep, Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
        if (dep == null)
        {
            throw new ArgumentNullException("dep");
        }

        foreach (var cd in this.ImplementedContracts.Values)
        {
            cd.Behaviors.Add(new MyInstanceProvider(dep));
        }
    }
}

public class MyInstanceProvider : IInstanceProvider, IContractBehavior
{
    private readonly IDependency dep;

    public MyInstanceProvider(IDependency dep)
    {
        if (dep == null)
        {
            throw new ArgumentNullException("dep");
        }

        this.dep = dep;
    }

    #region IInstanceProvider Members

    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        return this.GetInstance(instanceContext);
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        return new MyService(this.dep);
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {
        var disposable = instance as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }

    #endregion

    #region IContractBehavior Members

    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.InstanceProvider = this;
    }

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
    }

    #endregion
}

Зарегистрируйте MyServiceHostFactory в файле MyService.svc или используйте MyServiceHost непосредственно в коде для сценариев самостоятельного размещения.

Вы можете легко обобщить этот подход, и на самом деле некоторые контейнеры DI уже сделали это за вас (подсказка: Windsor's WCF Facility).

119
ответ дан 24 November 2019 в 04:32
поделиться

Ответ Марка с помощью IInstanceProvider правильный.

Вместо использования настраиваемой фабрики ServiceHostFactory можно также использовать настраиваемый атрибут (например, MyInstanceProviderBehaviorAttribute ). Получите его из атрибута , сделайте так, чтобы он реализовал IServiceBehavior и реализовал метод IServiceBehavior.ApplyDispatchBehavior , например

// YourInstanceProvider implements IInstanceProvider
var instanceProvider = new YourInstanceProvider(<yourargs>);

foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
    foreach (var epDispatcher in dispatcher.Endpoints)
    {
        // this registers your custom IInstanceProvider
        epDispatcher.DispatchRuntime.InstanceProvider = instanceProvider;
    }
}

Затем примените атрибут к классу реализации службы

[ServiceBehavior]
[MyInstanceProviderBehavior(<params as you want>)]
public class MyService : IMyContract

] Третий вариант: вы также можете применить поведение службы с помощью файла конфигурации.

11
ответ дан 24 November 2019 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: