如何在Silverlight应用程序中调用WCF服务?
您可以使用仅一次实例化的WCF服务代理(也称为单例模式),并在整个SL应用程序中使用它吗? 如果是这样,您是如何解决取消控件对WS-调用完成事件的订阅的问题的?
或者
每次调用时创建WCF服务代理?那么您在何处关闭代理?
如何在Silverlight应用程序中调用WCF服务?
您可以使用仅一次实例化的WCF服务代理(也称为单例模式),并在整个SL应用程序中使用它吗? 如果是这样,您是如何解决取消控件对WS-调用完成事件的订阅的问题的?
或者
每次调用时创建WCF服务代理?那么您在何处关闭代理?
这是我发现可行的应用程序结构:
For every service client partial class I have another generated partial class where for every service method I have a version that returns IObservable.
E.g. if my service client has a method GetAllMyDataAsync()
and event GetAllMyDataCompleted
the generated method signature will be IObservable<MyDataDto[]> GetMyData()
This method will deal with subscribing/unsubscribing to an event, authentication, error handling, and other infrastructure issues.
This way web-service call becomes simply:
new MyServiceClient().GetAllMyData().Subscribe(DoSomethingWithAllMyData)
With this I can easily join data from multiple requests, e.g. (strictly for demonstration purposes, don't try this in real app):
var des = (from d in new MyServiceClient().GetMyDataItem()
from e in new MyServiceClient().GetDataItemEnrichment(d)
select new EnrichedData { Data = d, Enrichment = e});
des.Subscribe(DoSomethingWithEnrichedData);
Once application gets more complex (e.g. data is shared by multiple components, you add messaging that dynamically updates initially retrieved data, etc.) it's helpful to add another element in the stack - Model.
Therefore if I have a service MyDataService
I'd have a model class called MyDataServiceModel
. It will be registered in the container as singleton and it will be injected into viewmodels that needs it. Thus viewmodels talk to this class when they need data (so rather than calling MyServiceClient.GetAllMyData
it would call MyDataServiceModel.GetAllMyData
.
This way viewmodels are completely independent of WCF stack (easier to mock, easier to test) Additionally these model classes take care of: