自托管WCF服务:如何从托管应用程序访问实现服务合同的对象?

Rob*_*ert 7 c# data-binding wpf wcf

我在WPF客户端中自托管WCF服务.我想显示服务在用户界面中收到的数据.每次收到一些数据时,都应更新用户界面.

"App.xaml.cs"中的代码如下所示

    private ServiceHost _host = new ServiceHost(typeof(MyService));

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        _host.Open();
    }

    private void Application_Exit(object sender, ExitEventArgs e)
    {
        _host.Close();
    }
Run Code Online (Sandbox Code Playgroud)

如何从托管WPF应用程序获取实现服务合同的对象实例?


谢谢大家的答案.

我没有看到的是ServiceHost的构造函数允许传递服务的实例而不是其类型.

所以我现在做的是:

  • 在服务实现中使用ObservableCollection
  • 将服务配置为单例(请参阅burningmonk的注释)
  • 绑定到我的WPF应用程序中的ObservableCollection
  • 使用数据绑定属性DataContext获取服务的实例
  • 将它传递给ServiceHost的构造函数

结果:单例WCF服务中的每个更新都反映在UI中.

快乐!

the*_*onk 13

正如marc_s所说,您正在创建PerCall/PerSession WCF服务,并且会在每个会话的每个请求/第一个请求上创建一个新实例.

您可以在它周围构建一些管道,以便实例在收到新请求时可以通知服务主机,但这不是一个简单的练习,如果您决定使用它,您需要注意内存泄漏的可能性要执行此操作的事件 - 未实现弱事件模式,您的WCF服务实例可能会被搁置,因为事件处理程序仍然保留对它们的引用,除非您记得在处理WCF服务实例时通知主机取消订阅.

相反,这里有两个可能使您更容易实现目标的想法:

如果您的服务可以成为单例,请使用Single InstanceContextMode,在这种情况下,您将创建一个实现服务合同并托管它的新实例:

// instance will be your WCF service instance
private ServiceHost _host = new ServiceHost(instance); 
Run Code Online (Sandbox Code Playgroud)

这样您就可以访问将检索客户端请求的实例.

或者,您可以将所有托管实例都设为虚拟"fascades",它们共享一个实际处理请求的静态类:

[ServiceContract]
interface IMyService { ... }

interface IMyServiceFascade : IMyService { ... }

// dummy fascade
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall]
public class MyServiceFascade : IMyServiceFascade 
{ 
    private static IMyService _serviceInstance = new MyService();

    public static IMyService ServiceInstance { get { return _serviceInstance; } }

    public int MyMethod()
    {
       return _serviceInstance.MyMethod();
    }
    ... 
}

// the logic class that does the work
public class MyService : IMyService { ... }

// then host the fascade
var host = new ServiceHost(typeof(MyServiceFascade));

// but you can still access the actual service class
var serviceInstance = MyServiceFascade.ServiceInstance;
Run Code Online (Sandbox Code Playgroud)

如果可能的话,我会说你应该采用第一种方法,让生活变得更轻松!