使用Shared Project共享程式與資源

by vivid 9. 三月 2016 10:26

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N160316901
出刊日期:2016/3/9
開發工具:Visual Studio 2015 Update 1
版本:.NET Framework 4.6、C# 6

在這篇文章之中,我將介紹Visual Studio 2015工具中獨立的範本專案 – 「Shared Project(共享專案)」。Shared Project可以讓你在不同類型的專案之中,例如主控台、WPF專案,共享程式碼。「Shared Project」最早是在Visual Studio 2013 Update 2版本中出現,現在已內建在Visual Studio 2015工具之中。

Shared Project(共享專案)支援以下類型的檔案,包含C#類別、HTML、XAML、JavaScript、圖片檔、資源檔、樣式表…等等。可以讓你在多種不同類型的專案之中,共享程式碼,如主控臺應用程式(Console)、WPF、Web應用程式,或Windows Universal Application。

在Shared Project(共享專案)之中,你可以搭配條件式編譯指示詞(Conditional compilation directives),如「#if」,為特定專案或平台來撰寫程式碼。

為了方便說明,我們來利用Visual Studio 2015工具,建立Shared Project(共享專案)來說明要如何使用它。

 

建立Shared Project(共享專案)

利用Visual Studio 2015來建立Shared Project(共享專案),從「File」-「New」-「Project」,在「New Project」對話盒中,確認視窗上方.NET Framework的目標版本為「.NET Framework 4.6」或以上,選取左方「Installed」-「Templates」-「Visual C#」程式語言,從「Windows」分類中,選取「Shared Project」,適當設定專案名稱與專案存放路徑,按下「OK」鍵,請參考下圖所示:

clip_image002

圖 1:建立Shared Project(共享專案)。

從Visual Studio 2015開發工具-「Solution Explorer」視窗- 「MyShared Project」專案上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目,開啟「Add New Item」對話盒,從右上方文字方塊輸入「Class」關鍵字搜尋,選取「Class」,設定類別名稱為「Utils」,然後按下「Add」按鈕,建立新類別,請參考下圖所示:

clip_image004

圖 2:建立新類別。

在類別之中,加入以下程式碼,利用條件式編譯指示詞(Conditional compilation directives)判斷語法,若在主控台應用程式中,使用到共享專案中的類別程式,則利用Console類別的WriteLine方法印出除錯訊息到主控台;若是在網站應用程式使用時,則使用Response.Write印出除錯訊息到網頁:

 

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;

namespace MySharedProject {
  public class Utils {
    public static void ShowMsg( string n ) {
#if MyConsole
        Console.WriteLine("Hello " + n);
#elif MyWebApp
        HttpContext.Current.Response.Write("Hello " + n);
#endif
    }
  }
}

 

加入主控台專案(Console Application)

使用Visual Studio 2015 建立主控台專案,從「Solution Explorer」視窗中,選取方案項目,按滑鼠右鍵,從快捷選單中,選取「Add」-「New Project」項目,從「Visual C#」分類中,選取「Console Application」項目,設定名稱為「MyConsoleApp」,然後按下「OK」按鈕,請參考下圖所示:

clip_image006

圖 3:加入主控台專案(Console Application)。

下一步,讓主控台類型程式參考Shared Project(共享專案)。在「Solution Explorer」視窗,選取「MyConsoleApp」專案,按滑鼠右鍵,從快捷選單選擇「Add」-「Reference」項目,勾選「Shared Project」分頁中的「MySharedProject」專案,這樣就可以在Console專案中引用Shared Project,請參考下圖所示:

clip_image008

圖 4:在Console專案中引用Shared Project。

然後我們在父專案(MyConsoleApp)加入程式碼,在Main方法中直接叫用MySharedProject.Utils.ShowMsg方法印出除錯訊息:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyConsoleApp {
  class Program {
    static void Main( string [ ] args ) {
      MySharedProject.Utils.ShowMsg( "Mary" );
    }
  }
}

 

接著在主控台專案中,自定一個條件式編譯指示詞(Conditional compilation directives)。雙擊方案總管「MyConsoleApp」專案下方的「Properties」節點,開啟專案屬性頁面。在「Build」分頁中,設定「Conditional compilation symbols」的值為「MyConsole」,而MySharedProject專案屬性頁則不必做任何的設定,請參考下圖所示:

clip_image010

圖 5:自定一個條件式編譯指示詞(Conditional compilation directives)。

按CTRL + F5執行主控台應用程式,則主控台將印出除錯訊息,請參考下圖所示:

clip_image012

圖 6:主控台印出除錯訊息。

乍看之下,Shared Project(共享專案)與Class Library(類別庫)專案非常的相像,不過實際上運作的方式完全不同。Shared Project用來共享原始程式碼(Source Code),而類別庫用來共用編譯過的組件(Assembly)。使用ildasm.exe工具檢視MyConsoleApp專案產生出的組件資訊,你將會發現Shared Project(共享專案)在編譯時,會將專案中的內容編譯成為主控台專案的一部分,請參考下圖所示:

clip_image014

圖 7:MyConsoleApp專案產生出的組件資訊。

因此當你開啟主控台專案的csproj檔案,可以看到檔案中包含一個<Import>標籤,這表示編譯主控台專案時,會將Shared Project(共享專案)匯入專案之中:

<Import Project="..\MySharedProject\MySharedProject.projitems" Label="Shared" />

因為將Shared Project(共享專案)當作是在MyConsoleApp專案的一部分,因此只需要在MyConsoleApp專案的屬性頁設定「MyConsole」除錯符號,而MySharedProject專案則不必設定。

 

參考類別庫專案

和Shared Project不同的是,類別庫專案(Class Library)以外部組件的方式,編譯成dll檔案,被主控台專案中引用,讓我們在方案中加入一個類別庫專案做測試。從「Solution Explorer」視窗中,選取方案項目,按滑鼠右鍵,從快捷選單中,選取「Add」-「New Project」,從「Visual C#」分類中,選取「Class Library」項目,設定名稱為「MyClassLibrary」,然後按下「OK」按鈕,請參考下圖所示:

clip_image016

圖 8:參考類別庫專案。

若開啟MyConsoleApp主控台專案的csproj檔案,可以看到其中包含一個<ProjectReference>的設定:

<ProjectReference Include="..\MyClassLibrary\MyClassLibrary.csproj">
<Project>{a613933f-73e5-4297-b31f-de47082ad65f}</Project>
<Name>MyClassLibrary</Name>
</ProjectReference>

因為MyClassLibrary專案中的程式會使用到HttpContext類別,因此在MyClassLibrary專案中要加入System.Web.dll組件的參考。在「Solution Explorer」視窗,選取「MyClassLibrary」專案,按滑鼠右鍵,從快捷選單選擇「Add」-「Reference」項目,勾選「Assemblies」分頁中的「System.Web」組件,請參考下圖所示:

clip_image018

圖 9:引用System.Web.dll組件的參考。

在類別庫專案預設的Class1.cs檔案之中,加入以下程式碼,定義MyClassUtils類別,撰寫ShowMsg方法,利用Response.Write印出除錯訊息:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace MyClassLibrary {
  public class MyClassUtils {
    public static void ShowMsg( string n ) {
#if MyConsole
          Console.WriteLine("Hello " + n);
#elif MyWebApp
      HttpContext.Current.Response.Write( "Hello " + n );
#endif
    }
  }

}


 

最後設定MyConsoleApp主控台程式參考MyClassLibrary專案,在「Solution Explorer」視窗,選取「MyConsoleApp」專案,按滑鼠右鍵,從快捷選單選擇「Add」-「Reference」項目,勾選「Projects」-「Sloution」分頁中的「MyClassLibrary」專案,這樣就可以在Console專案中引用類別庫,請參考下圖所示:

clip_image020

圖 10:在Console專案中引用類別庫。

修改MyConsoleApp專案中的 Main方法,叫用MyClassLibrary.MyClassUtils.ShowMsg來印出除錯訊息:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyConsoleApp {
  class Program {
    static void Main( string [ ] args ) {
      MySharedProject.Utils.ShowMsg( "Mary" );
      MyClassLibrary.MyClassUtils.ShowMsg("candy" );     
    }
  }
}


 

按CTRL + F5執行MyConsoleApp專案,這次只有印出MySharedProject.Utils.ShowMsg這行程式碼印出訊息,而MyClassLibrary.MyClassUtils.ShowMsg這段程式碼沒有印出除錯訊息,請參考下圖所示:

clip_image022

圖 11:測試叫用類別庫組件程式的結果。

使用ildasm.exe工具檢視MyConsoleApp.exe組件資訊,MyClassLibrary類別庫專案被視為是外部組件,請參考下圖所示:

clip_image024

圖 12:類別庫專案被視為外部組件。

正是因為類別庫專案並沒有定義條件式編譯符號「MyConsole」的關係,MyClassUtils. ShowMsg方法的訊息不會印出到主控台,讓我們為MyClassLibrary專案定義條件式編譯符號,雙擊方案總管「MyClassLibrary」專案下方的「Properties」節點,開啟專案屬性頁面。在「Build」分頁中,設定「Conditional compilation symbols」的值為「MyConsole」,請參考下圖所示:

clip_image026

圖 13:為MyClassLibrary專案定義條件式編譯符號。

這樣執行MyConsoleApp程式時,MyClassUtils. ShowMsg方法的訊息才會印出到主控台,請參考下圖所示:

clip_image028

圖 14:測試叫用類別庫組件程式的結果。

在Web應用程式專案中使用Shared Project(共享專案)

最後,我們來探討一下在Web應用程式的專案中該如何使用Shared Project(共享專案),從「Solution Explorer」視窗中,選取方案項目,按滑鼠右鍵,從快捷選單中,選取「Add」-「New Project」項目,從「File」-「New」-「Project」項目,在「New Project」對話盒中,,選取左方「Installed」-「Templates」-「Visual C#」程式語言,從「Web」分類中,選取「ASP.NET Web Application」,設定專案名稱為「MyWebApplication」,以及專案存放路徑,並按下「OK」鍵。請參考下圖所示:

clip_image030

圖 15:加入Web應用程式的專案。

在「New ASP.NET Project」對話盒中選取「Empty」項目,勾選下方的「Web Forms」項目,然後按下「OK」按鈕建立專案,請參考下圖所示:

clip_image032

圖 16:建立空白Web Forms專案。

而在Web Application類型的專案中,使用Add Reference功能時,並無「Shared Project」分頁,因此沒法參考到Shared Project(共享專案),請參考下圖所示:

clip_image034

圖 17:預設Web Application類型的專案無法參考共享專案。

解法方案如下,先使用「Unload Project」功能將Web Applictaion從方案暫時移除,選取「Solution Explorer」視窗中的「MyWebApplication」專案,按滑鼠右鍵,從快捷選單中選取「Unload Project」項目,請參考下圖所示:

clip_image036

圖 18:「Unload Project」功能。

選取「Solution Explorer」視窗中的「MyWebApplication」專案,按滑鼠右鍵,從快捷選單中選取「Edit MyWebApplication.csproj」項目,編輯專案檔案,請參考下圖所示:

clip_image038

圖 19:編輯專案檔案。

修改<ProjectTypeGuids>項目,預設Web Application類型的專案,應該會看到以下的設定,包含兩個ID:

<ProjectTypeGuids>
{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
</ProjectTypeGuids>

第一個項目是Web Application的ID,第二個項目描述的是C#專案,先移除第一個ID,修改設定如下:

<ProjectTypeGuids> {fae04ec0-301f-11d3-bf4b-00c04f79efbc} </ProjectTypeGuids>

儲存專案檔案,接著重新載入編輯過的專案,選取「Solution Explorer」視窗中的「MyWebApplication」專案,按滑鼠右鍵,從快捷選單中選取「Reload Project」項目,請參考下圖所示:

clip_image040

圖 20:「Reload Project」項目。

此時便可以選取「Solution Explorer」視窗的「MyWebApplication」專案,按滑鼠右鍵,從快捷選單中選取「Add Referece」項目,「Reference Manager」對話盒中就會出現「Shared Project」分頁,讓專案能夠參考到 Shared Project(共享專案),請參考下圖所示:

clip_image042

圖 21:參考 Shared Project(共享專案)。

完成參考動作之後,「Solution Explorer」視窗的「MyWebApplication」專案下,「References」項目下就會多出一個MySharedProject節點,請參考下圖所示:

clip_image044

圖 22:引用「Shared Project」。

接著照前面的步驟,使用「Unload Project」功能,將<ProjectTypeGuids>項目的設定改回來,選取「Solution Explorer」視窗中的「MyWebApplication」專案,按滑鼠右鍵,從快捷選單中選取「Unload Project」項目,修改設定如下:

<ProjectTypeGuids>
{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
</ProjectTypeGuids>

完成參考動作之後,那麼就可以在Web應用程式專案中,使用到Shared Project(共享專案),先加入一個Web Form測試,選取「Solution Explorer」視窗中的「MyWebApplication」專案,按滑鼠右鍵,從快捷選單中選取「Add」-「New Item」項目,然後選取「Web Form」,取一個名稱,然後按下「Add」按鈕,請參考下圖所示:

clip_image046

圖 23:加入「Web Form」項目。

雙擊ASPX設計畫面,進入程式設計視窗,在Page_Load事件處理常式中,加入以下程式碼,叫用MySharedProject.Utils.ShowMsg("Mary" )印出訊息到瀏覽器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyWebApplication {
  public partial class WebForm1 : System.Web.UI.Page {
    protected void Page_Load( object sender , EventArgs e ) {
      MySharedProject.Utils.ShowMsg("Mary" );
    }
  }
}

 

執行之前,要設定條件式編譯指示詞(Conditional compilation directives)。雙擊方案總管「MyWebApplication」專案下方的「Properties」節點,開啟專案屬性頁面。在「Build」分頁中,設定Conditional compilation symbols的值為「MyWebApp」,請參考下圖所示:

clip_image048

圖 24:設定條件式編譯除錯符號。

選取「Solution Explorer」視窗中的ASPX檔案,按滑鼠右鍵,從快捷選單中選取「View In Browser」項目,執行網頁,執行結果請參考下圖所示:

clip_image050

圖 25:網頁測試結果。

類別庫與Shared Project(共享專案)

最後總結一下類別庫與Shared Project(共享專案)的差異:

類別庫:

  • 共享組件
  • 編譯成一個組件。
  • 只能包含C#程式 (若Visual Basic類型的專案,則只能包含Visual Basic程式)

Shared Project(共享專案):

  • 共享原始程式碼與資源檔
  • 可以包含C#程式、XAML檔案、JavaScript檔案…等共用的資源。
  • 可以在多種類型的專案中使用Shared Project,包含:Console、Windows Forms、WPF、Web Application、Universal App..等等。
  • 不會編譯成一個組件,它將編譯成父專案的一部份。
  • 可以使用條件式編譯指示詞(Conditional compilation directives),以撰寫特定平台所需的程式碼。

Tags:

.NET Framework | .NET Magazine國際中文電子雜誌 | NET 開發 | 許薰尹Vivid Hsu | Visual Studio

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List