一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

技巧:使用可擴展對象模式擴展HttpApplication

  概述

  HttpApplication對象對于做ASP.NET開發的朋友,我想沒有人不熟悉它。在ASP.NET開發中,經常避免不了要在HttpApplication中執行一些操作,如使用了ASP.NET MVC框架,就會在Application_Start 事件中避免不了這樣的路由規則配置代碼:

protected void Application_Start()
{
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

RouteTable.Routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}

  如果僅僅是這一條,看起來倒不覺的有什么問題,但如果同時在應用程序中使用了工作流,又避免不了在Application_Start出現啟動工作流運行時的代碼:

protected void Application_Start()
{
// 注冊路由規則
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

// 啟動工作流
WorkflowRuntime workflowRuntime = new WorkflowRuntime("workflowServicesConfig");
ExternalDataExchangeService
externalDataExchangeService = new ExternalDataExchangeService();
workflowRuntime.AddService(externalDataExchangeService);
workflowRuntime.StartRuntime();
}

  試想一下,現在我們僅僅是有了ASP.NET MVC路由規則的配置、WF運行時的啟動,如果在應用程序中使用某種DI框架,如微軟的Unity,是不是又避免不了要出現這樣的容器初始化代碼呢?

protected void Application_Start()
{
// 注冊路由規則
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

// 啟動工作流
WorkflowRuntime workflowRuntime
= new WorkflowRuntime("workflowServicesConfig");
ExternalDataExchangeService externalDataExchangeService
= new ExternalDataExchangeService();
workflowRuntime.AddService(externalDataExchangeService);
workflowRuntime.StartRuntime();

// 初始化DI容器
IContainerContext repositoryContainer
= ContainerManager.GetContainer("repositoryContainer");
repositoryContainer.Initialize();
}

  再看看Application_Start事件中的代碼,有ASP.NET MVC的工作,有WF的工作,也有Unity的工作,不知道將來還會有什么?這些原本互相之間沒有任何聯系的代碼,現在卻同時堆在了一起,當每一部分(或者說每一個框架)變化的時候,都會涉及到Application_Start中代碼的修改,顯然違反了OCP原則。那么有沒有一種機制,讓這些互不相干的模塊之間互相獨立,各自發生變化時不影響對HttpApplication?此時我們就需要對HttpApplication進行擴展,提供一個擴展點,讓其他模塊的程序附加到HttpApplication上面。

  可擴展對象模式

  我們知道WCF提供了非常完美的擴展機制,幾乎在服務執行過程中的每一個環節上都提供有擴展點,如ServiceHostBase、OperationContext、InstanceContext、IContextChannel,這些對象都屬于可擴展對象,它們都通過Extensions屬性獲取用于所有擴展的集合。我們能不能使用這種方式對HttpApplication也進行擴展呢,答案自然是肯定的。查閱一下MSDN就會知道在System.ServiceModel命名空間下面提供了這樣的一組接口:IExtensibleObject、IExtension和IExtensionCollection,這是可擴展對象模式中最重要的三個接口,也只有這三個接口。

  IExtensibleObject自然是定義了可擴展對象,即我們要對誰進行擴展,它的定義非常簡單,僅僅是提供了一個只讀的屬性Extensions,用來提供所有擴展對象的集合,如下代碼所示:

public interface IExtensibleObject<T> where T : IExtensibleObject<T>
{
IExtensionCollection<T> Extensions { get; }
}

  IExtension定義了擴展對象的契約,使對象可以通過聚合擴展另一個對象(此處的另一個對象,就是指上面所講的擴展宿主IExtensibleObject),在IExtension中定義了兩個非常重要的方法Attach和Detach方法,分別用來提供聚合或解聚的通知。

public interface IExtension<T> where T : IExtensibleObject<T>
{
void Attach(T owner);
void Detach(T owner);
}

  當一個擴展對象IExtension附加到可擴展對象的擴展集合中時,它的Attach方法將會被調用;反之如果從集合中移除一個擴展對象時,它的Detach方法會被調用。這一點我們可以通過Reflector來得到驗證,如下代碼所示:

protected override void InsertItem(int index, IExtension<T> item)
{
lock (base.SyncRoot)
{
item.Attach(this.owner);
base.InsertItem(index, item);
}
}

protected override void RemoveItem(int index)
{
lock (base.SyncRoot)
{
base.Items[index].Detach(this.owner);
base.RemoveItem(index);
}
}

  最后一個接口是IExtensionCollection,它是IExtension對象的集合。

  對HttpApplication進行擴展

  下面我們就看一下如何使用可擴展對象模式對HttpApplication進行擴展,首先定義可擴展對象,讓ExtensibleHttpApplication派生于HttpApplication,并實現了IExtensibleObject接口,泛型的參數類型就是它自身,如下代碼所示:

public class ExtensibleHttpApplication : HttpApplication,
IExtensibleObject<ExtensibleHttpApplication>
{
private IExtensionCollection<ExtensibleHttpApplication> _extensions;

public ExtensibleHttpApplication()
{
this._extensions = new ExtensionCollection<ExtensibleHttpApplication>(this);
}

public IExtensionCollection<ExtensibleHttpApplication> Extensions
{
get
{
return this._extensions;
}
}
}

  有了可擴展的HttpApplication之后,需要在HttpApplication中實現任何功能,都可以作為一個擴展附加到ExtensibleHttpApplication上去,如實現ASP.NET MVC路由,可以定義一個如下代碼所示的擴展對象:

public class MvcHttpApplication : IExtension<ExtensibleHttpApplication>
{
public void Attach(ExtensibleHttpApplication owner)
{
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

RouteTable.Routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}

public void Detach(ExtensibleHttpApplication owner)
{
//nothing
}
}

  同樣如果要在HttpApplication中啟動Workflow,可以再針對Workflow定義一個擴展對象,如下示例代碼所示:

public class WorkflowHttpApplication : IExtension<ExtensibleHttpApplication>
{
private WorkflowRuntime workflowRuntime;
public void Attach(ExtensibleHttpApplication owner)
{
workflowRuntime = new WorkflowRuntime("workflowServicesConfig");
ExternalDataExchangeService externalDataExchangeService
= new ExternalDataExchangeService();
workflowRuntime.AddService(externalDataExchangeService);
workflowRuntime.StartRuntime();
}

public void Detach(ExtensibleHttpApplication owner)
{
workflowRuntime.StopRuntime();
}
}

  我們已經定義好了相應的擴展對象,只需要在相應的HttpApplication把擴展對象附加到ExtensibleHttpApplication上即可,修改Global.asax中的代碼如下所示:

public class MvcApplication : ExtensibleHttpApplication
{
protected void Application_Start()
{
this.Extensions.Add(new MvcHttpApplication());
this.Extensions.Add(new WorkflowHttpApplication());
}
}

  現在代碼是不是看起來優雅多了?現在如果要在Application_Start中,添加另外一些執行代碼,只需要編寫相應的擴展對象,并將其添加到Extension集合中即可。也許有朋友會問,這樣每添加一些新的代碼,還是要修改Application_Start中的代碼啊?別忘了,可以通過配置可以解決這個問題,WCF中的擴展不也是可以采用配置方式實現,不是嗎?同樣,如果我們需要在Application_End事件中釋放某些對象,可以直接從擴展集合中移除它,此時將會調用它的Detach方法。

  總結

  本文介紹了如何使用WCF中提供的可擴展對象模式擴展HttpApplication,事實上可擴展對象模式的作用遠不在此,它可以擴展.NET類庫中任何我們想對其進行擴展的對象,或者是一個自定義的類型,都可以使用可擴展對象模式對其進行擴展。

NET技術技巧:使用可擴展對象模式擴展HttpApplication,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 91视频国产91久久久 | 91视频一区 | 天堂在线观看 | www.一区| 91秒拍国产福利一区 | 日本久久综合 | 91在线免费视频观看 | 狠狠色噜噜狠狠狠狠2021天天 | 色视频免费网站 | 欧美日韩亚洲国产一区二区三区 | 精品国产网红福利在线观看 | 国内精品久久久久久麻豆 | 国产一区二三区 | 国产精品久久1024 | 天干天干夜天干天天爽 | 思思九九热 | 日日夜夜2017 | 中文字幕一区二区三区四区五区人 | 国产精品免费一区二区三区四区 | 色噜噜噜视频 | 国内精品久久影视免费 | 一级做a爰片性色毛片新版的 | 婷婷色网站 | 美女毛片大全 | 全部免费69堂在线视频 | 国产91久久久久久久免费 | 人人干人人看 | 五月婷婷丁香在线 | 岛国a香蕉片不卡在线观看 岛国不卡 | 日本高清午夜色wwwσ | 都市激情亚洲综合 | 永久免费观看午夜视频在线 | 天天色国产 | 欧美在线黄 | 色播视频在线播放 | 亚洲无吗在线视频 | 亚洲美女一区 | 中文字幕亚洲无线码在线一区 | 五月婷婷开心网 | 久久精品国产乱子伦多人 | 五月婷网站 |