注意,我们可以使用FireEvent()触发任意类型的事件,而不用考虑参数的个数,因为我们使用了params object数组。
最后,应用程序需要为包含了事件契约的发布服务公开一个终结点:
<services>例B-6演示了PublishService<T>的实现。
<service name = "MyPublishService">
<endpoint
address = "..."
binding = "..."
contract = "IMyEvents"
/>
</service>
</services>
例B-6 实现PublishService<T>
public abstract class PublishService<T> where T : class
{
protected static void FireEvent(params object[] args)
{
StackFrame stackFrame = new StackFrame(1);
string methodName = stackFrame.GetMethod( ).Name;
//解析显式接口实现
if(methodName.Contains("."))
{
string[] parts = methodName.Split('.');
methodName = parts[parts.Length-1];
}
FireEvent(methodName,args);
}
static void FireEvent(string methodName,params object[] args)
{
PublishPersistent(methodName,args);
PublishTransient(methodName,args);
}
static void PublishPersistent(string methodName,params object[] args)
{
T[] subscribers = SubscriptionManager<T>.GetPersistentList(methodName);
Publish(subscribers,true,methodName,args);
}
static void PublishTransient(string methodName,params object[] args)
{
T[] subscribers = SubscriptionManager<T>.GetTransientList(methodName);
Publish(subscribers,false,methodName,args);
}
static void Publish(T[] subscribers,bool closeSubscribers,string methodName,
params object[] args)
{
WaitCallback fire = delegate(object subscriber)
{
Invoke(subscriber as T,methodName,args);
if(closeSubscribers)
{
using(subscriber as IDisposable)
{}
}
};
Action<T> queueUp = delegate(T subscriber)
{
ThreadPool.QueueUserWorkItem(fire,subscriber);
};
Array.ForEach(subscribers,queueUp);
}
static void Invoke(T subscriber,string methodName,object[] args)
{
Debug.Assert(subscriber != null);
Type type = typeof(T);
MethodInfo methodInfo = type.GetMethod(methodName);
try
{
methodInfo.Invoke(subscriber,args);
}
catch(Exception e)
{
Trace.WriteLine(e.Message);
}
}
}