2013年5月18日 星期六

ASP.NET WebForm 使用 Simple Injector 選擇不同的 Repository

這一篇也是延續文,主要是延續上一篇「ASP.NET WebForm 使用分層的 Repository 類別庫專案」,而架構一樣沿用之前 ASP.NET MVC - Model 系列文章的 Repository 分層架構,如下:

ASP.NET MVC 的 Model 使用 ADO.NET

ASP.NET MVC 的 Model 使用 Enterprise Library 6 Data Access Application Block

ASP.NET MVC - 使用 Simple Injector 讓 Model 三選一

既然 ASP.NET MVC 可以使用 Simple Injector 選擇不同的資料存取方式,而前面文章也討論過可以將 ASP.NET MVC 所使用的分層讓 ASP.NET WebForm 網站來使用,所以同樣地也可以讓 ASP.NET WebForm 網站透過 Simple Injector 來選擇不同的資料存取方式,而不用去大幅更改到原本的網站程式。

這一篇不打算廢話太多(我哪一篇文章的廢話有少過咧),就請各位仔細看清楚文章的程式內容。

 


ASP.NET WebForm 要加入使用 Simple Injector 並沒有像 ASP.NET MVC 那樣方便,在 NuGet 上可以找到為 ASP.NET MVC 做好的整合套件,只要安裝再加以調整之後就可以使用,然而 ASP.NET WebForm 就必須要多做一些手工作業後才能使用,而且在 ASPX 的 Code Behind 使用上也跟 ASP.NET MVC 在 Controller 內的使用方式也大大不同,以下就從頭到尾做操作說明。

 

首先加入的其他兩個 Repository 專案參考,

image

Web.Config 加入 Entity Framework 使用的 ConnectionString

image

 

透過 NuGet 加入 Simple Injector

開啟 NuGet,輸入「Simple Injector」查詢相關套件,安裝「Simple Injector」與「Simple Injector ASP.NET Integration」(直接安裝後者就會把相依的套件給安裝進來),

image

 

修改 Global.asax

在 WebForm 裡安裝 Simple Injector 之後並不會有個「SimpleInjectorInitializer.cs」讓我們直接在裡面加入要註冊使用的類別,而是我們要在 Global.asax 裡面去加入(或是也可以新增一個 SimpleInjectorInitializer.cs 檔案,然後 Global.asax 去呼叫使用)。

在 Global.asax 裡加入以下的程式內容:

#region -- Simple Injector Bootstrap --
 
private static Container container;
 
[System.Diagnostics.DebuggerStepThrough]
public static TService GetInstance<TService>()
    where TService : class
{
    return container.GetInstance<TService>();
}
 
private void SimpleInjectorBootstrap()
{
    //=====================================================================================
    // 1. Create a new Simple Injector container
    var container = new Container();
 
    //=====================================================================================
    // 2. Get Repository Assembly Name
 
    string repositoryType = WebConfigurationManager.AppSettings["RepositoryType"].ToString().Trim();
 
    //=====================================================================================
    // 3. Register Type for Repository
 
    string repositoryAssemblyName = repositoryType;
    string classFullName = string.Concat(repositoryType, ".CategoryRepository");
 
    //這邊加入類別的註冊
    container.Register
    (
        typeof(IEmployeeRepository),
        ReflectionHelper.GetType(repositoryType, string.Concat(repositoryType, ".EmployeeRepository"))
    );
    
    //=====================================================================================
    // 4. Store the container for use by Page classes.
 
    container.Verify();
    Global.container = container;
 
}
 
#endregion

然後在 Global.asax 的 Application_Start() 方法內加入 SimpleInjectorBootstrap() 的使用,

image

 

修改 Employee 的 List.aspx 與 Details.aspx

原本的 List.aspx 是直接使用 Sample.Repository.ADONET,現在改用 Simple Injector 來取代這樣的直接引用,改為我們去修改 Web.Config 裡的 appSetting,來決定看是要使用哪一種 Repository,

image

上面的內容修改為以下的內容,拿掉 Repository 命名空間的直接使用,建構式也做調整,從註冊到 container 的類別裡取得 instance,

image

同樣的,Details.aspx 也做一樣的修改,

image

 

執行

在 WebForm 的專案裡也加入使用 MiniProfiler,有關 WebForm 加入使用 MiniProfiler 可以參考「MiniProfiler with ASP.NET WebForms」這篇文章,而三種不同的資料存取方式的切換是去修改 Web.Config 的 AppSetting 值,不需要再去修改程式。

image

image

image

 

Sample.Repository.ADONET

第一次執行

image

image

第二次執行

image

 

Simple.Repository.EntLibDAAB

第一次執行

image

image

第二次執行

image

 

Sample.Repository.EF

第一次執行

image

image

image

第二次執行

image

image

 

上面的 Repository 抽換使用,所看到的調整就只有上面所呈現,至於什麼控制項的 DataBind 或是頁面上的調整都沒有去動到,因為我們只是抽換資料存取的 Repository 而已,並不會直接影響頁面上的控制項,控制項無須也不必知道後端資料是使用什麼樣的存取方式,甚至於也無須知道所使用的資料儲存體是什麼,頁面的 Code Behind 程式只要知道在 IEmployeeRepository 這個介面裡要用哪一種方法來取得資料就可以,其餘的就交由 Simple Injector 以及各個有實作 Sample.Repository.Interface 的類別庫專案。

 


從上一篇「ASP.NET WebForm 使用分層的 Repository 類別庫專案」到這一篇,兩篇說明了如何在同一個分層架構裡沿用原本給 ASP.NET MVC 網站使用的 Repository,其實資料如何存取以及商業邏輯怎麼處理,這兩個與表現層是沒有直接的關係,所以表現層要用什麼技術或是什麼架構也不應該去直接影響資料存取與商業邏輯,無論我前端是使用 ASP.NET WebForm 還是 ASP.NET MVC,資料存取的方法只需要做一套,不會因為用 WebForm 或 MVC 而有所不同。

很多 ASP.NET WebForm 的開發人員對於物件導向與分層有一種「沒有必要這麼做」的觀念,因為他們所處理的專案規模大多都不是很大,甚至於好幾個時間點所做的專案都是同樣一種模式,所以對他們而言最快的處理方式就是 Copy Paste,然後所有的 UI 處理、商業邏輯處理、資料存取都塞在同一個程式裡,這樣的方式是最快的,以後只要有類似且少數幾個地方做變動的案子(變動最大的地方應該只有 Layout 畫面),只需要把之前做的專案再複製一份然後再修改就好了……

其實我想要說的是,難道以後開發的案子都是這樣嗎?往後數年的工作永遠都是 Copy Paste 嗎?難後兩三年過去之後,因為都是一直做 Copy Paste 的工作,而覺得程式開發不過就是如此,所以就會想要轉換工作或是轉換職業?這個業界有太多那種基礎不夠然後因為時間或是年資到了而由 PG 轉 SD, SA, PM,但是這樣基礎不夠的狀態下所規劃、設計的專案夠穩當嗎? 

小案子有小案子的做法,時間趕有時間趕的作法,但是每個專案都是同樣的作法是不會有進步的,倘若日後要面對規模較大的案子時,如果還是繼續沿用過往處理小案子時的作法,只會讓自己陷入更大的困境當中,所以在做小案子的時候就可嘗試加入一些不一樣的作法,試著去做改變,慢慢累積經驗,一旦經驗足夠了,面對規模更大的案子就可游刃有餘而輕鬆應付(當然很多事情不是這麼簡單地)。

 

PS.
我會把這個系列文章所建置的專案做個整理,然後找個時間把 Source Code 讓大家下載,雖然不是多麼複雜難做的內容,但實際看到整個專案總比在文章裡只看到部分來得清楚吧!

 

相關系列文章

ASP.NET MVC

ASP.NET MVC 的 Model 使用 ADO.NET

ASP.NET MVC 的 Model 使用 Enterprise Library 6 Data Access Application Block

ASP.NET MVC - 使用 Simple Injector 讓 Model 三選一

ASP.NET WebForm

ASP.NET WebForm 使用分層的 Repository 類別庫專案

ASP.NET WebForm 使用 Simple Injector 選擇不同的 Repository

範例原始檔

ASP.NET MVC 與 ASP.NET WebForm 使用 Simple Injector 切換選擇不同 Repository 原始碼下載

 

以上

1 則留言:

  1. 最近遇到維護WebForm的案子,感謝板主分享~
    最後心得真的很真實XD,遇到一堆Copy Paste...維護到懷疑人生

    回覆刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。