很久以前我上次在这里问一个问题:) 现在是时候再问一次了,因为我没有任何想法来实现我需要的东西......
需要注意的一件重要事情 - 我正在为 Windows Phone 7.5 编写应用程序,它等于 Silverlight 3.0,因此您可能建议的某些功能在那里不起作用(比如 iClientMessageInspector 在 SL 3.0/WP7.5 中不存在,或者我不能通过使用反射设置某个类的私有字段 - 值得一提)。
好的,我的目标是订阅生成的 Web 服务代理类的每个事件,其中事件名称以“已完成”结尾,并了解 Web 操作是否因异常而失败(所以 - 目标是有一个地方来处理错误来自项目中的所有 Web 服务 - 例如,由于会话结束,用户未经过身份验证)。
我有一个类来创建所有 Web 服务客户端(在我的项目中大约有 4 个 Web 服务引用),因此只有一个方法来处理所有 Web 发起的 Web 服务调用中出现的所有异常可能很有用-服务类型。此类名称是 WebManager,它包含创建 Web 服务的属性(一种 Web 服务类型的 1 个属性),如下所示:
public SomeServiceReference.AuthenticationServiceClient AuthenticationService
{
get
{
var web = new SomeServiceReference.AuthenticationServiceClient();
// here i plan to subscribe to xxxCompleted event
// i'll provide final code below
return web;
}
}
在生成的 Web 服务代理类(Reference.cs)中,我有几个事件,每次 Web 操作结束时都会触发它们,它们都以这种模式命名:“Web_service_OperationName”+“Completed”,示例:
public event System.EventHandler<SomeOperationCompletedEventArgs> SomeOperationCompleted;
另一件重要的事情要提到: SomeOperationCompletedEventArgs 是从标准 System.ComponentModel.AsyncCompletedEventArgs 继承的,所以在 WebManager 类中我可以编写一些方法并将其用作默认事件处理程序:
public void TestEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
// analyze web-call results here:
// do we have exception or web-operation completed successfully
// if (e.Error != null) { /*do something there*/ }
}
所以我可以这样做,以便订阅 SomeOperationCompleted 事件并了解操作是否失败:
public SomeServiceReference.AuthenticationServiceClient AuthenticationService
{
get
{
var web = new SomeServiceReference.AuthenticationServiceClient();
web.SomeOperationCompleted += TestEventHandler;
return web;
}
}
这种方法效果很好,如果您在 TestEventHandler 方法中放置断点,您将在“e”参数中看到操作详细信息。
但这不是为 Reference.cs 中的每个事件编写所有事件订阅的最佳方式,因此我试图找到一种方法来自动化它。
我尝试为 Reference.cs 中的所有事件添加新的事件处理程序,如下所示:
public SomeServiceReference.AuthenticationServiceClient AuthenticationService
{
get
{
var web = new SomeServiceReference.AuthenticationServiceClient();
var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
var type = web.GetType();
var eventsCompleted = type.GetEvents(bindingFlags).Where(e => e.Name.EndsWith("Completed")).ToArray();
var methodInfo = this.GetType().GetMethod("TestEventHandler");
foreach (var eventInfo in eventsCompleted)
{
//Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodInfo);
Delegate handler = Delegate.CreateDelegate(typeof(System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs>), this, methodInfo);
//eventInfo.AddEventHandler(this, handler);
MethodInfo addHandler = eventInfo.GetAddMethod();
Object[] addHandlerArgs = { handler };
//var p = addHandler.GetParameters();
addHandler.Invoke(web, addHandlerArgs);
}
return web;
}
}
这种方法不像 SomeOperationCompleted 那样工作,System.EventHandler <SomeOperationCompletedEventArgs> delegate
并且 TestEventHandler 方法具有System.EventHandler <System.ComponentModel.AsyncCompletedEventArgs>
参数类型。同时我可以写web.SomeOperationCompleted += TestEventHandler;
我应该如何修改我的代码,以便能够在我的 WebManager 类中订阅这些事件?