已發布·持續改進
C# 指南 · 4/6
本章目前僅提供英文版。
As a codebase grows, you split it into several projects and start pulling in libraries written by others. .NET organizes this around four units: assemblies, projects, solutions, and NuGet packages. This chapter explains how they fit together, then shows how to reference projects, add packages, and produce output you can ship.
| Unit | What it is |
|---|---|
| Assembly | The compiled output: a .dll library or an executable, containing code plus type metadata. |
| Project | One .csproj file that produces one assembly; it lists sources, target framework, and dependencies. |
| Solution | A list of projects you build and test together, stored as .sln or the newer XML-based .slnx. |
| NuGet package | A .nupkg archive of assemblies and metadata, downloaded from a feed such as nuget.org. |
Keep namespaces and assemblies apart in your head. A namespace is a logical naming scope; an assembly is a physical unit of deployment. One assembly can contain many namespaces, and a single namespace can span several assemblies.
A common layout is an executable, a class library holding the core logic, and a test project, all in one solution. These commands create the skeleton:
mkdir Shop && cd Shop
dotnet new sln -n Shop
dotnet new classlib -o src/Shop.Core
dotnet new console -o src/Shop.Cli
dotnet sln add src/Shop.Core src/Shop.Cli
# let Shop.Cli use the code in Shop.Core
dotnet add src/Shop.Cli reference src/Shop.Core
dotnet build # from the solution folder, this builds every projectAdding the reference writes an entry like this into Shop.Cli.csproj. At build time the referenced project is compiled first and its assembly is copied into the consumer's output folder.
<ItemGroup>
<ProjectReference Include="..\Shop.Core\Shop.Core.csproj" />
</ItemGroup>Only types and members marked public are visible to other projects. internal means visible within the same assembly only, which is how libraries hide implementation details. A top-level type with no modifier defaults to internal.
// src/Shop.Core/PriceCalculator.cs
namespace Shop.Core;
public static class PriceCalculator
{
public static decimal WithTax(decimal price) => Round(price * (1 + TaxRate));
internal const decimal TaxRate = 0.1m; // visible only inside Shop.Core
private static decimal Round(decimal value) => Math.Round(value, 2);
}// src/Shop.Cli/Program.cs
using Shop.Core;
Console.WriteLine($"{PriceCalculator.WithTax(100m):F2}"); // 110.00
// PriceCalculator.TaxRate is internal, so it is not accessible hereIf a test project needs to exercise internal members, the library can grant access to that specific assembly with the InternalsVisibleTo attribute.
NuGet is the package manager for .NET. dotnet add package records a PackageReference in the project file, and packages are restored automatically on the next build.
cd src/Shop.Cli
dotnet add package Humanizer # add the latest stable version
dotnet add package Humanizer --version <version> # pin a specific version
dotnet list package # show referenced packages
dotnet list package --outdated # show packages with newer versions
dotnet remove package Humanizer # remove it again
dotnet restore # run the restore step on its ownusing Humanizer;
Console.WriteLine("order_created_at".Humanize()); // Order created at
Console.WriteLine(TimeSpan.FromMinutes(95).Humanize(2)); // 1 hour, 35 minutesBefore adopting a package, check its download count, how recently it was updated, its license, and which frameworks it supports. When many projects must agree on package versions, central package management lets you set them once in a Directory.Packages.props file at the solution root, and shared build settings can live in Directory.Build.props.
dotnet build output is meant for development. To produce something you can deploy to another machine, use dotnet publish:
# framework-dependent: smaller, but the target machine needs the .NET runtime
dotnet publish src/Shop.Cli -c Release -o out
# self-contained: bundles the runtime, nothing to install on the target
dotnet publish src/Shop.Cli -c Release -r linux-x64 --self-contained -o out-linux
# bundle everything into a single executable file
dotnet publish src/Shop.Cli -c Release -r win-x64 --self-contained -p:PublishSingleFile=trueThe -r option takes a runtime identifier (RID) such as win-x64, linux-x64, or osx-arm64. If startup time and memory footprint matter, add <PublishAot>true</PublishAot> to the project to compile ahead of time to native code, though libraries that lean heavily on reflection may not be compatible. To share a library as a NuGet package of your own, run dotnet pack -c Release.
dotnet sln add and connect them with dotnet add reference.public; keep implementation details internal.dotnet add package records a PackageReference, and packages are restored at build time.dotnet publish, choosing framework-dependent, self-contained, single-file, or native AOT output.
0 則留言
登入 · 登入後即可留言。
來留下第一則留言吧。