如果项目中的功能要求需要经过一系列的处理。可以采用管道-过滤器模式组织这些处理。每一个处理就是一个过滤器。组织过滤器的管线对象就是管道。
管道模式适用于一系列确定/已知的步骤处理。
原始的管道模型可以像下面这样:
/// <summary> /// 处理消息 /// </summary> public abstract class Context { } /// <summary> /// 过滤器 /// </summary> /// <typeparam name="T"></typeparam> public interface IFilter<T> where T : Context { T Handle(T message); } /// <summary> /// 管道 /// </summary> /// <typeparam name="T"></typeparam> public class PipeBase<T> where T : Context { protected IList<IFilter<T>> filter = new List<IFilter<T>>(); public T Message { set; get; } public void ProcessHandle() { foreach (var s in filter) { s.Handle(Message); } } public void AddFilter( IFilter<T> f ) { } public void RemoveFilter(IFilter<T> f) { } }
asp.net的请求事件 就是一个管道-过滤器模式,通过一系列的管道事件处理HttpContext,简要分析下ASP.NET的事件请求管道。
事件管理:微软的事件管理是构建了一个 EventHandlerList 其实现如下:
public sealed class EventHandlerList : IDisposable { // Fields private ListEntry head; private Component parent; // Methods [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public EventHandlerList(); [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] internal EventHandlerList(Component parent); public void AddHandler(object key, Delegate value); public void AddHandlers(EventHandlerList listToAddFrom); public void Dispose(); private ListEntry Find(object key); public void RemoveHandler(object key, Delegate value); // Properties public Delegate this[object key] { get; set; } // Nested Types private sealed class ListEntry { // Fields internal Delegate handler; internal object key; internal EventHandlerList.ListEntry next; // Methods public ListEntry(object key, Delegate handler, EventHandlerList.ListEntry next); } }
HttpAplication中通过采用
public event EventHandler AcquireRequestState { add { this.AddSyncEventHookup(EventAcquireRequestState, value, RequestNotification.AcquireRequestState); } remove { this.RemoveSyncEventHookup(EventAcquireRequestState, value, RequestNotification.AcquireRequestState); } }
把事件加入到事件管理器中。
事件发现:
private void RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers)
{
RequestNotification notification;
RequestNotification notification2;
this.RegisterIntegratedEvent(appContext, "AspNetFilterModule", RequestNotification.LogRequest | RequestNotification.UpdateRequestCache, 0, string.Empty, string.Empty, true); this._moduleCollection = this.GetModuleCollection(appContext); if (handlers != null) { this.HookupEventHandlersForApplicationAndModules(handlers); } HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(context, this); this._currentModuleCollectionKey = "global.asax"; try { this._hideRequestResponse = true; context.HideRequestResponse = true; this._context = context; this.Init(); } catch (Exception exception) { this.RecordError(exception); Exception error = context.Error; if (error != null) { throw error; } } finally { this._context = null; context.HideRequestResponse = false; this._hideRequestResponse = false; } this.ProcessEventSubscriptions(out notification, out notification2); this._appRequestNotifications |= notification; this._appPostNotifications |= notification2; for (int i = 0; i < this._moduleCollection.Count; i++) { this._currentModuleCollectionKey = this._moduleCollection.GetKey(i); IHttpModule module = this._moduleCollection.Get(i); ModuleConfigurationInfo info = _moduleConfigInfo[i]; module.Init(this); this.ProcessEventSubscriptions(out notification, out notification2); if ((notification != 0) || (notification2 != 0)) { this.RegisterIntegratedEvent(appContext, info.Name, notification, notification2, info.Type, info.Precondition, false); } } this.RegisterIntegratedEvent(appContext, "ManagedPipelineHandler", RequestNotification.ExecuteRequestHandler | RequestNotification.MapRequestHandler, RequestNotification.EndRequest, string.Empty, string.Empty, false); }
注意 this.RegisterIntegratedEvent(appContext, "AspNetFilterModule", RequestNotification.LogRequest | RequestNotification.UpdateRequestCache, 0, string.Empty, string.Empty, true);
this.RegisterIntegratedEvent(appContext, info.Name, notification, notification2, info.Type, info.Precondition, false);
this.RegisterIntegratedEvent(appContext, "ManagedPipelineHandler", RequestNotification.ExecuteRequestHandler | RequestNotification.MapRequestHandler, RequestNotification.EndRequest, string.Empty, string.Empty, false);
this._currentModuleCollectionKey = "global.asax";
上面就会把在GLOBAL ,Filter,httpmodule 里面定义的事件加入到事件管理列表中。