从WCF服务器接收值

时间:2017-08-31 13:06:13

标签: c# wcf

我已经设置了WCF服务器和客户端,所有工作都很顺利,我可以在服务器上调用该方法并接收从该调用初始化的对象...很棒。

我遇到的问题是服务器在启动时收到一些参数,我无法看到的是我如何从服务器获取这些值,因为看起来我无法从服务器获取消息或预先初始化的类服务器本身。

除了在服务器第一次接收文件然后从服务器方法读取该文件时将其保存到文件之外,有没有办法提供此信息?

由于

1 个答案:

答案 0 :(得分:1)

最简单的方法是拥有一个单例服务对象。这可以通过使用ServiceBehavior属性标记服务类并将此对象传递给ServiceHost构造函数来完成:

[ServiceContract]
public interface IExampleService
{
    [OperationContract]
    int GetInitValue();
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class ExampleService : IExampleService
{
    private readonly int initValue;

    public ExampleService(int initValue)
    {
        this.initValue = initValue;
    }

    public int GetInitValue() => initValue;
}

// ...

// public ServiceHost(object singletonInstance, params Uri[] baseAddresses)
var host = new ServiceHost(new ExampleService(someValue)));

host.AddServiceEndpoint(typeof(IExampleService),
    new WSHttpBinding(), "http://localhost:8080");
host.Open();

当单例模式不合适时,可以使用依赖注入,例如与Unity:

var container = new UnityContainer();

container
    .RegisterType<IExampleService, ExampleService>()
        // When service object is created, someValue is passed to it's constructor
        new InjectionConstructor(someValue));

var host = new ServiceHost(typeof(ExampleService));

host.AddServiceEndpoint(typeof(IExampleService),
    new WSHttpBinding(), "http://localhost:8080")
    .EndpointBehaviors.Add(new UnityEndpointBehavior(container));

host.Open();

// ...

class UnityEndpointBehavior : IEndpointBehavior
{
    private readonly IUnityContainer container;

    public UnityEndpointBehavior(IUnityContainer container)
    {
        this.container = container;
    }

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

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

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
        EndpointDispatcher endpointDispatcher)
    {
        endpointDispatcher.DispatchRuntime.InstanceProvider =
            new UnityInstanceProvider(container, endpoint.Contract.ContractType);
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
}

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