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

Posted

技术标签:

【中文标题】自托管 WCF 服务:如何从托管应用程序访问实现服务合同的对象?【英文标题】:Self-hosted WCF service: How to access the object(s) implementing the service contract from the hosting application? 【发布时间】:2011-03-28 23:55:32 【问题描述】:

我在 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();
    

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


感谢大家的回答。

我没有看到的是 ServiceHost 的构造函数允许传递服务的 instance 而不是它的 type

所以我现在要做的是:

在服务实现中使用 ObservableCollection 将服务配置为单例(参见 theburningmonk 的评论) 绑定到我的 WPF 应用程序中的 ObservableCollection 使用数据绑定属性DataContext获取服务实例 传递给ServiceHost的构造函数

结果:单例 WCF 服务中的每次更新都会反映在 UI 中。

快乐!

【问题讨论】:

您已经获得了课程 (MyService)。我想你的意思是:如何获取对象实例。 谢谢,是的,我改了问题。 【参考方案1】:

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

您可以围绕它构建一些管道,以便实例在收到新请求时通知服务主机,但这不是一件容易的事,如果您决定这样做,您需要注意内存泄漏的可能性继续使用事件来执行此操作 - 如果不实现弱事件模式,您的 WCF 服务实例可能会一直徘徊,因为事件处理程序仍然持有对它们的引用,除非您记得在 WCF 服务实例被处置时通知主机取消订阅。

相反,这里有两个想法可能会让您更轻松地实现目标:

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

// instance will be your WCF service instance
private ServiceHost _host = new ServiceHost(instance); 

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

或者,您可以让所有托管实例成为虚拟“门面”,它们共享一个实际处理请求的静态类:

[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;

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

【讨论】:

谢谢您的精彩评论,为我指明了正确的方向。【参考方案2】:

没有可用的 MyService 类型的单个对象实例 - 默认情况下,WCF 使用每次调用模型,例如对于每个传入的请求,将创建一个 MyService 的新实例,用于处理该请求,然后将其释放。

因此,除非有至少一个正在运行的请求,否则很可能没有任何服务实例。

你到底想用这个实现什么?也许您需要重新考虑您的方法并从服务类实例开始 - 它有一个属性 .Host 链接回托管该特定服务实例的主机。

【讨论】:

以上是关于自托管 WCF 服务:如何从托管应用程序访问实现服务合同的对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何实现自托管 WCF 数据服务(http://localhost:1234/myDataService.svc/...)

在 WCF 自托管服务中指定 Singleton 服务

从 Windows 应用程序访问托管在 IIS 上的 WCF 服务时出现问题

如何从服务“内部”的代码访问托管在 IIS 中的 WCF 服务的 web.config

WCF 服务 - 自托管服务不起作用

如何从托管在另一台服务器上的 Web 应用程序调用客户端计算机托管的 Wcf 服务?