.NET Core系列 :3 、使用多個項目
通過前面的兩篇文章,我們已經知道如何創建新的項目,如何生成並運行我們的應用程序,也知道(大致) project.json 文件中的內容是什么意思。但大多數項目往往也需要多個項目或引用的類庫。我們要創建類庫項目和應用程序項目。在應用程序中,如何引用我們的類庫。
創建應用項目 File -> New Application
這個很熟悉了吧,輸入下面的命令:
mkdir DotnetNewApp
cd DotnetNewApp
dotnet new
dotnet restore
dotnet build
dotnet run
[root@Mono ~]# mkdir DotnetNewApp
[root@Mono ~]# cd DotnetNewApp/
[root@Mono DotnetNewApp]# dotnet new
Created new C# project in /root/DotnetNewApp.
[root@Mono DotnetNewApp]# dotnet restore
log : Restoring packages for /root/DotnetNewApp/project.json...
log : Writing lock file to disk. Path: /root/DotnetNewApp/project.lock.json
log : /root/DotnetNewApp/project.json
log : Restore completed in 8774ms.
[root@Mono DotnetNewApp]# dotnet build
Project DotnetNewApp (.NETCoreApp,Version=v1.0) will be compiled because expecte d outputs are missing
Compiling DotnetNewApp for .NETCoreApp,Version=v1.0
Compilation succeeded.
0 Warning(s)
0 Error(s)
Time elapsed 00:00:03.7500023
[root@Mono DotnetNewApp]# dotnet run
Project DotnetNewApp (.NETCoreApp,Version=v1.0) was previously compiled. Skippin g compilation.
Hello World!
我們創建好了應用項目,接下來我們創建一個類庫項目
創建類庫項目 File -> New Library
dotnet new 默認創建的控制台項目,他還可以創建其他項目類型 :
[root@Mono DotnetNewApp]# dotnet new -t -h
Unrecognized type: -h
Avaiable types for C# :
- Console
- Web
- Lib
- xunittest
看這個輸出,單詞都拼錯了,Avaiable 應該是Available,已經被提了bug https://github.com/dotnet/cli/pull/3822 ,除了控制台,還可以創建Web,Lib和xunittest,項目類型和使用Visual Studio 2015一致。web是asp.net core 模板,xunittest是測試項目,Lib就是我們需要創建的類庫項目類型,所以我們將加上-t 參數指定為Lib,Scott Hanselman 的博文 Exploring dotnet new with .NET Core 講的也很詳細:
[root@Mono DotnetNewApp]# cd ..
[root@Mono ~]# mkdir DotnetNewLib
[root@Mono ~]# cd DotnetNewLib/
[root@Mono DotnetNewLib]# dotnet new -t Lib
Created new C# project in /root/DotnetNewLib.
[root@Mono DotnetNewLib]# pwd
/root/DotnetNewLib
我們創建完成了一個C#類庫項目 /root/DotnetNewLib
我們來對比下控制台和類庫項目的區別是什么?前面一篇文章《.NET Core系列 : 2 、project.json 這葫蘆里賣的什么葯》我們已經簡單提及。我們來看下類庫項目的project.json:
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable"
},
"dependencies": {},
"frameworks": {
"netstandard1.6": {
"dependencies": {
"NETStandard.Library": "1.6.0"
}
}
}
}
類庫的編譯選項buildOptions 少了 emitEntryPoint ,這是一個類庫,所以不需要入口。依賴的框架不是netcoreapp1.0,而是用了一個netstandard1.6替代,上面一篇文章我們簡要說明了一下,本質上來說netcoreapp1.0和.NET 4.6.3 都是NETStardard 1.6的實現,Mono 也正在調整NETStardard,https://github.com/mono/mono/tree/netstandard。
本質上來說,NETStandard.Library 是一個目標最低支持基礎類庫,這樣就可以更好的向前兼容性,在現有的平台出現新的版本時(如.net core 1.1 甚至 2.0)而無需重新發布新的變化。具體參考 https://github.com/dotnet/corefx/blob/master/Documentation/architecture/net-platform-standard.md ,目前最新的表格:
如何理解這個表格
- 如果一個類庫指定.NET平台標准1.3版本,那么它僅能夠運行在.NET Framework 4.6或更新的框架、Universal Windows Platform 10(UWP)、DNX Core 5.0和Mono/Xamarin這些平台上。
- 如果一個類庫指定.NET平台標准1.3版本,那么它能夠引用(原文:consume)所有來自之前的.NET平台標准的版本(1.2、1.1、1.0)。
如果我們想要我們的類庫項目,也可以更廣泛地使用,比如舊版本的.Net項目也可以用, 我們可以降低修改為 netstandard1.0,這意味着所有.Net 4.5 或更高版本的運行時兼容,再加上Windows Phone Silverlight (8.0 + 8.1)。值得注意的.Net 4.5 以下版本不兼容這個新的NetStandard 版本化方案。在我們的控制台應用程序,我們針對Microsoft.NETCore.App 的依賴項。這是指類型的平台,並且在我們的應用程序的運行時上聲明依賴項。
我們的控制台程序將要依賴於我們這個類庫項目做些計算邏輯,我們就用它來做個2個數相乘吧,修改Class1為Calculator,Method1修改為Multi:
namespace DotnetNewLib
{
public class Calculator
{
public int Multi(int x,int y)
{
return x * y;
}
}
}
下面進入我們今天的重點是項目的引用.
項目引用Project References
引用項目和引用Nuget包不同的地方主要是 "target": "project" 這個屬性,這和前面的Microsoft.NETCore.App 的依賴屬性"type": "platform"類似。
下面我們給我們的控制台應用添加類庫DotnetNewLib的依賴,在DotnetNewApp的project.json 添加,文件內容如下:
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"DotnetNewLib":{
"target":"project"
}
},
"imports": "dnxcore50"
}
}
}
這么寫有個前提是你的DotnetNewApp 和DotnetNewLib文件夾有相同的父文件夾,這里有兩件事需要注意,每當你dotnet build DotnetNewApp,他就會以遞歸方式嘗試dotnet build DotnetNewLib。第二件需要注意的是build而不是執行restore,你需要確保這兩個項目都運行了dotnet restore,當然你可以在他們的父文件夾執行dotnet restore。所有的子文件夾里面的project.json 都會被恢復。
接下來,我們在控制台應用DotnetNewApp里調用DotnetNewLib的乘法:
using System;
using DotnetNewLib;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Calculator calc = new Calculator();
var result = calc.Multi(9,8);
Console.WriteLine($"Hello World is {result} ");
}
}
}
編譯和運行
我們切換到DotnetNewApp 文件夾下,我們現在可以編譯和運行這個應用了,同時也會編譯我們的類庫項目DotnetNewLib。
[root@Mono DotnetNewApp]# dotnet build
Project DotnetNewLib (.NETStandard,Version=v1.6) will be compiled because expected outputs are missing
Compiling DotnetNewLib for .NETStandard,Version=v1.6
Compilation succeeded.
0 Warning(s)
0 Error(s)
Time elapsed 00:00:02.8849475
Project DotnetNewApp (.NETCoreApp,Version=v1.0) will be compiled because dependencies changed
Compiling DotnetNewApp for .NETCoreApp,Version=v1.0
Compilation succeeded.
0 Warning(s)
0 Error(s)
Time elapsed 00:00:03.0273700
[root@Mono DotnetNewApp]# dotnet run
Project DotnetNewLib (.NETStandard,Version=v1.6) was previously compiled. Skipping compilation.
Project DotnetNewApp (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Hello World is 72
到這里我們成功構建了一個類庫項目和一個控制台項目,控制台引用類庫項目完成乘法運算,這雖然是一個很簡單的多項目應用,我們通過這個最簡單的項目講解了dotnet core的多項目應用如何進行開發和注意事項。