每次调用端点时,自托管 WCF 服务全局对象似乎都是新创建的

Self hosted WCF service global object appears to be newly created every time an endpoint is invoked

按照教程 here 我在 windows 服务中自行托管 WCF 服务。我的 WCF 服务包含一个我定期更新的全局对象。我想通过服务端点将该对象序列化为 JSON 和 return 那个 JSON 字符串。当我访问调用服务上的序列化方法的端点时,我得到的似乎是全局的全新实例。服务设置为[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

我正在以与教程相同的方式实例化:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MyWindowsService: ServiceBase
{public ServiceHost serviceHost = null;

    public Service()
    {
        ServiceName = "MyService";
    }

    public static void Main()
    {
        ServiceBase.Run(new MyWindowsService());
    }

    protected override void OnStart(string[] args)
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
        }

        serviceHost = new ServiceHost(typeof(MyWCFService));
        serviceHost.Open();
    }

    protected override void OnStop()
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
            serviceHost = null;
        }
    }

我的 WCF 服务如下所示:

public class MyWCFService: IWCFService
{
    private myObject = mySerializableObject;

    public MyWCFService()
    {
        myObject = new MySerializableObject();
        myObject.Init();
    }

    public Stream GetJSON()
    {
        MemoryStream stream = new MemoryStream();
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(MySerializableObject));

        ser.WriteObject(stream, myObject);

        string jsonString = Encoding.ASCII.GetString(stream.ToArray());


        byte[] resultBytes = Encoding.UTF8.GetBytes(jsonString);
        WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
        return new MemoryStream(resultBytes);
    }
}

如果我GETGetJSON端点,字符串returned是一个全新初始化的对象。如果我中断 GetJSON 方法,myObject 将显示所有新初始化的值。在 MySerializableObject 更新代码中放置一个断点表明更新正确发生并保存到内存中的对象。

运行 普通控制台应用程序中的相同代码工作正常。为什么会出现差异?我是否错误地处理了全局?

弄清楚了...我遇到了几个问题。

  1. 所示,我的 InstanceContextMode 声明 没有装饰正确的服务,所以它仍然是 运行 默认的每次调用上下文 - 因此,每个连接上都有一个新的状态对象。
  2. O'Reilly 告诉我我没有创建我的单身人士 实例正确。旁注,当使用实例创建 ServiceHost 时,您可以在构造函数或 App.config 中显式指定基本 URI。这让我有些困惑,因为我 运行 在构造函数而不是配置中传递了它的许多示例。

这是我为后代所做的工作实施:

[ServiceContract(Namespace = "http://my.super.original.namespace")]
public interface IWCFService
{
    [OperationContract, WebGet]
    Stream GetJSON();
}

//Decorator goes on WCF service, not the Windows service
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MyWCFService : IWCFService
{
    private StateObject _myStateObject;

    public MyWCFService()
    {
        _myStateObject = new StateObject();
        _myStateObject.Init();
    }

    public Stream GetJSON()
    {
        .
        .
        .
        return "JSON String Here";
    }
}

public class MyWindowsService : ServiceBase
{
    public ServiceHost serviceHost = null;
    private readonly MyWcfService _wcfSingleton;

    public MyWindowsService()
    {
        ServiceName = "WindowsServiceNameHere";
        _wcfSingleton = new MyWCFService();
    }

    public static void Main()
    {
        ServiceBase.Run(new MyWindowsService());
    }

    // Start the Windows service.
    protected override void OnStart(string[] args)
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
        }

        //load WCF Singleton Instance and open it for connections
        serviceHost = new ServiceHost(_wcfSingleton);
        serviceHost.Open();
    }

    protected override void OnStop()
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
            serviceHost = null;
        }
    }
}