自托管 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/...)
从 Windows 应用程序访问托管在 IIS 上的 WCF 服务时出现问题