C# 开发环境搭建(Avalonia UI、Blazor Web UI、Web API 应用示例)

C# 文档

NuGet

.NET SDK 下载

安装 .NET SDK

在这里插入图片描述

安装完验证

dotnet -h
# .NET SDK 版本
dotnet --version
# .NET SDK 的列表
dotnet --list-sdks
# .NET 运行时的列表
dotnet --list-runtimes
# .NET 安装和计算机环境详细信息
dotnet --info

在这里插入图片描述

  • 安装时正常会自动添加 PATH
# /usr/local/share/dotnet:~/.dotnet/tools
echo $PATH

在这里插入图片描述

VS Code 配置

C# 开发插件

C#
C# Dev Kit
Avalonia for VSCode

settings.json

  • 配置 Code Runner
{
	"code-runner.executorMap": {
		"csharp": "cd $dir && dotnet run $fileName"
	}
}
  • 创建一个 控制台应用
# 安装模板包
dotnet new install Microsoft.NET.Runtime.WebAssembly.Templates
# 根据 console 模板创建项目
dotnet new console -o ./demo -n demo
# 根据 console 模板创建项目,未指定名称则使用输出目录的名
dotnet new console -o ./demo
  • 运行 demo 项目

在这里插入图片描述

  • 或者终端执行命令
dotnet run

WPF UI 框架

WPF(Windows Presentation Foundation)是微软推出的基于Windows 的用户界面框架。

注: 本人是 Mac 电脑无法演示。

Avalonia UI 框架

Avalonia是一个强大的框架,使开发人员能够使用.NET创建跨平台应用程序。它使用自己的渲染引擎绘制UI控件,确保在Windows、macOS、Linux、Android、iOS和WebAssembly等不同平台上具有一致的外观和行为。这意味着开发人员可以共享他们的UI代码,并在不同的目标平台上保持统一的外观和感觉。

创建 Avalonia 项目

# 安装 Avalonia 模板
dotnet new install Avalonia.Templates
# 列出已安装的模板
dotnet new list

在这里插入图片描述

# 创建 Avalonia 项目
dotnet new avalonia.app -o demo
cd demo
# 运行项目
dotnet run

在这里插入图片描述

Avalonia 官方示例

git clone https://github.com/AvaloniaUI/Avalonia.Samples.git
cd Avalonia.Samples
cd ./src/Avalonia.Samples/CompleteApps/SimpleToDoList
  • SimpleToDoList.csproj 修改为当前环境 .NET SDK 版本
<TargetFramework>net8.0</TargetFramework>
  • 运行项目
dotnet run

在这里插入图片描述

Avalonia 桌面 UI 库

在这里插入图片描述

git clone https://github.com/kikipoulet/SukiUI.git
cd SukiUI/SukiUI.Demo
dotnet run

在这里插入图片描述

Blazor Web UI 框架

注: Blazor允许Web开发人员使用C#代替JavaScript创建Web应用程序。他们还可以重用.NET Silverlight代码。另外,Blazor应用程序由使用C#,HTML和CSS实现的可重复使用的Web UI组件组成。由于客户端和服务器代码都是用C#编写的,因此开发人员可以共享代码和库。

创建应用

dotnet new blazor -o BlazorApp

在这里插入图片描述

项目结构

  • Program.cs 是启动服务器以及在其中配置应用服务和中间件的应用的入口点。
  • 在 Components 目录中:
    • App.razor 为应用的根组件。
    • Routes.razor 配置 Blazor 路由器。
    • Pages 目录包含应用的一些示例网页。
  • BlazorApp.csproj 定义应用项目及其依赖项。
  • Properties 目录中的 launchSettings.json 文件为本地开发环境定义不同的配置文件设置。创建项目时会自动分配端口号并将其保存在此文件上。

在这里插入图片描述

  • 运行应用
dotnet run

在这里插入图片描述

ASP.NET Core 控制器创建 Web API

dotnet --list-sdks
dotnet new webapi -controllers -f net8.0 -o demo

在这里插入图片描述

  • 项目结构
名称描述
Controllers/包含公共方法公开为 HTTP 终结点的类。
Program.cs配置服务和应用的 HTTP 请求管道,包含应用的托管入口点。
ContosoPizza.csproj包含项目的配置元数据。
ContosoPizza.http包含直接从 Visual Studio Code 测试 REST API 的配置。

在这里插入图片描述

  • 运行应用
dotnet run

在这里插入图片描述

dotnet 命令

dotnet new

dotnet new -h
  • 列出要使用 dotnet new 运行的可用模板
dotnet new list

在这里插入图片描述

  • 在 NuGet.org 上搜索 dotnet new 支持的模板
dotnet new search console

在这里插入图片描述

  • 安装模板包
dotnet new install Microsoft.NET.Runtime.WebAssembly.Templates

在这里插入图片描述

  • 卸载模板包
# 列出已安装的模板及其详细信息
dotnet new --uninstall
# 卸载 WebAssembly 模板包
dotnet new uninstall Microsoft.NET.Runtime.WebAssembly.Templates

在这里插入图片描述

  • 更新已安装的模板包
dotnet new update -h
# 检查已安装模板包更新
dotnet new update --check-only
# 更新已安装模板包
dotnet new update

dotnet build

  • 生成项目及其所有依赖项
dotnet build -h

dotnet run

  • 无需任何显式编译或启动命令即可运行源代码
dotnet run -h
dotnet run --no-build

dotnet tool

dotnet tool -h
# 列出全局或本地安装的工具
dotnet tool list
<think> 我们正在讨论Blazor商业级项目的代码结构设计。根据用户之前的问题,他已经了解了Blazor依赖注入,现在需要了解在Visual Studio中如何组织一个商业级Blazor项目的代码结构。 商业级项目通常意味着: 1. 项目规模较大,需要良好的模块划分 2. 可维护性、可扩展性要求高 3. 遵循最佳实践和设计模式 4. 包含测试项目 在Blazor中,我们可以采用分层架构。常见分层方式包括: - 表现层(Blazor项目本身) - 应用层(服务层) - 领域层(领域模型) - 基础设施层(数据访问等) 但具体到Blazor项目,我们还需要考虑Blazor Server和Blazor WebAssembly两种模式的差异。这里我们设计一个通用的结构,可以适应两种模式。 以下是一个推荐的Blazor商业级项目在Visual Studio中的解决方案结构: ``` 解决方案名称 (例如: MyBlazorApp) │ ├── src/ │ ├── MyBlazorApp.Client/ # Blazor WebAssembly 客户端项目(如果是Blazor Server则不需要) │ │ ├── Pages/ # 页面组件 │ │ ├── Shared/ # 共享组件(布局、通用组件等) │ │ ├── wwwroot/ # 静态资源 │ │ ├── _Imports.razor # 全局导入 │ │ ├── App.razor # 应用根组件 │ │ ├── Program.cs # 客户端入口 │ │ └── ... │ │ │ ├── MyBlazorApp.Server/ # Blazor Server 服务端项目(如果是WebAssembly,则作为宿主项目) │ │ ├── Controllers/ # Web API 控制器(如果需要提供API) │ │ ├── Pages/ # 如果使用服务端页面(通常不需要,因为Blazor Server主要使用Razor组件) │ │ ├── Services/ # 服务端特定的服务(如数据库访问服务) │ │ ├── Program.cs # 服务端入口 │ │ ├── Startup.cs # (.NET 5及以前)配置服务、中间件 │ │ └── ... │ │ │ ├── MyBlazorApp.Shared/ # 共享项目(客户端和服务端共享) │ │ ├── Models/ # 数据模型(DTOs、实体等) │ │ ├── Services/ # 服务接口和实现(如果实现可以在两边共享) │ │ ├── Components/ # 共享的Razor组件 │ │ └── ... │ │ │ └── MyBlazorApp.Core/ # 核心项目(领域层) │ ├── Domain/ # 领域模型(实体、值对象、领域服务等) │ ├── Application/ # 应用层(用例、服务接口) │ └── ... │ ├── test/ │ ├── MyBlazorApp.Client.Tests/ # 客户端测试项目(单元测试、集成测试) │ ├── MyBlazorApp.Server.Tests/ # 服务端测试项目 │ ├── MyBlazorApp.Core.Tests/ # 核心层测试项目 │ └── ... │ └── docs/ # 文档 ``` 详细说明: 1. **MyBlazorApp.Client** 项目:如果是Blazor WebAssembly模式,这是必须的。它包含所有的UI组件和客户端逻辑。注意,在Blazor Server模式下,这个项目是不需要的,因为UI组件会放在服务端项目中。 2. **MyBlazorApp.Server** 项目:在Blazor Server模式下,这是主项目;在Blazor WebAssembly模式下,这个项目作为宿主(Host)项目,用于托管WebAssembly客户端,并提供API服务。 3. **MyBlazorApp.Shared** 项目:这个项目包含客户端和服务端都可以共享的代码,例如: - 共享的Razor组件(如果使用WebAssembly,这些组件可以在客户端和服务端项目中被引用) - 共享的服务接口(服务实现可能不同,因为客户端可能通过HttpClient调用API,而服务端直接访问数据库) - 共享的数据模型(DTOs) 4. **MyBlazorApp.Core** 项目:包含核心业务逻辑,与UI和基础设施无关。这里定义领域模型、应用服务接口(注意:实现可能在基础设施层)等。 5. **测试项目**:每个主要项目都有对应的测试项目。 在Blazor Server项目中,通常不需要单独的API控制器,因为可以直接通过服务端注入的服务来操作数据。但是,如果同时需要支持其他客户端(如移动应用),或者Blazor WebAssembly需要调用API,那么就需要在服务端项目中添加API控制器。 对于依赖注入的配置,可以在服务端项目的`Program.cs`(或`Startup.cs`)中配置服务。在客户端项目中,如果是WebAssembly,则在其`Program.cs`中配置客户端所需的服务。 共享服务的设计: - 在共享项目中定义服务接口(如`IDataService`) - 在服务端项目中实现该接口(如`DataService`,它可能使用Entity Framework Core访问数据库) - 在客户端项目中,通过HttpClient调用服务端API,因此客户端需要实现一个使用HttpClient的`DataService`(可以命名为`HttpDataService`),该实现位于客户端项目或共享项目中(如果共享项目可以引用`HttpClient`,但通常共享项目不引用,所以放在客户端项目中)。然后通过依赖注入,在客户端注册`IDataService`为`HttpDataService`。 或者,我们可以采用另一种方式:在服务端提供API控制器,然后在客户端直接使用`HttpClient`调用这些API,而不使用共享的服务接口(这样客户端和服务端解耦)。但共享接口可以保证两端的一致性。 推荐使用共享接口,这样在客户端和服务端可以保持相同的契约。具体做法: 在共享项目(`MyBlazorApp.Shared`)中定义接口: ```csharp public interface IWeatherForecastService { Task<WeatherForecast[]> GetForecastAsync(); } ``` 在服务端(`MyBlazorApp.Server`)中实现该接口: ```csharp public class WeatherForecastService : IWeatherForecastService { // 这里可以直接访问数据库 public Task<WeatherForecast[]> GetForecastAsync() { // 实现 } } ``` 然后在服务端的`Program.cs`中注册: ```csharp builder.Services.AddScoped<IWeatherForecastService, WeatherForecastService>(); ``` 在客户端(`MyBlazorApp.Client`)中,我们无法直接使用服务端的实现,所以我们需要创建一个通过HTTP调用服务的实现: ```csharp public class HttpWeatherForecastService : IWeatherForecastService { private readonly HttpClient _httpClient; public HttpWeatherForecastService(HttpClient httpClient) { _httpClient = httpClient; } public async Task<WeatherForecast[]> GetForecastAsync() { return await _httpClient.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast"); } } ``` 然后在客户端的`Program.cs`中注册: ```csharp builder.Services.AddScoped<IWeatherForecastService, HttpWeatherForecastService>(); ``` 注意:服务端需要有一个API控制器(例如`WeatherForecastController`)来提供`WeatherForecast`的API。 对于Blazor Server模式,由于组件在服务端运行,可以直接注入服务端实现的服务,因此不需要通过HttpClient调用。所以,在Blazor Server项目中,我们只需要在服务端注册服务,然后在组件中注入`IWeatherForecastService`即可。 总结:以上结构可以同时支持Blazor Server和Blazor WebAssembly模式,通过共享项目来复用DTO和接口,通过不同的服务实现来适配不同的运行模式。 此外,对于大型项目,我们还可以考虑使用CQRS模式、MediatR等,这些可以在核心项目和应用层中实现。 引用说明: 在用户提供的引用中,并没有直接关于Blazor商业项目结构的引用。但是,引用[1]提到了创建Blazor Server应用程序,我们可以据此推断用户可能使用Blazor Server。因此,在结构设计中,我们应同时考虑Server和WebAssembly两种模式,因为商业项目可能会根据需求选择其中一种或两者都支持。 根据以上内容,我们生成如下回答: </think> 以下是针对 Blazor 商业级项目在 Visual Studio 中的详细代码结构设计,采用分层架构和模块化思想,确保可维护性、可扩展性和高效协作: --- ### **一、分层架构设计** #### **1. 解决方案结构** ```markdown MyBlazorAppSolution/ ├── src/ # 源代码目录 │ ├── Presentation/ # 表现层(Blazor项目) │ ├── Application/ # 应用层(业务逻辑) │ ├── Domain/ # 领域层(核心业务模型) │ ├── Infrastructure/ # 基础设施层(数据/外部服务) │ └── Shared/ # 共享库(DTO/工具类) ├── tests/ # 测试目录 ├── docs/ # 文档目录 └── deploy/ # 部署脚本 ``` #### **2. 各层职责说明** | **层级** | **项目类型** | **关键内容** | |------------------|--------------------|-----------------------------------------------------------------------------| | **Presentation** | Blazor Server/WASM | `Pages/`(路由组件)、`Components/`(可复用组件)、`Layouts/`(布局) | | **Application** | .NET Class Library | `Services/`(应用服务)、`Features/`(CQRS命令查询)、`Exceptions/`(自定义异常) | | **Domain** | .NET Class Library | `Entities/`(领域实体)、`ValueObjects/`(值对象)、`Aggregates/`(聚合根) | | **Infrastructure**| .NET Class Library | `Persistence/`(EF Core)、`ExternalServices/`(API客户端)、`Caching/`(Redis) | | **Shared** | .NET Class Library | `Dtos/`(数据传输对象)、`Enums/`、`Extensions/`(扩展方法) | --- ### **二、关键目录详解** #### **1. Blazor表现层(Presentation)** ```markdown MyBlazorApp.Presentation/ ├── Pages/ │ ├── Admin/ # 管理后台路由组件 │ │ ├── Users.razor # 用户管理页 │ │ └── Products.razor │ ├── Public/ # 公共页面 │ └── App.razor # 根路由配置 ├── Components/ │ ├── UI/ # 基础UI组件 │ │ ├── CustomTable.razor │ │ └── ChartCard.razor │ ├── Forms/ # 表单组件 │ └── Layout/ │ ├── MainLayout.razor │ └── NavMenu.razor ├── Services/ # 前端服务 │ ├── AuthStateProvider.cs # 认证状态管理[^1] │ └── NotificationService.cs └── wwwroot/ # 静态资源 ``` #### **2. 基础设施层(Infrastructure)** ```csharp // 数据库上下文配置示例 public class AppDbContext : DbContext { public DbSet<User> Users { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置实体关系 modelBuilder.ApplyConfigurationsFromAssembly(typeof(UserConfiguration).Assembly); } } // 仓储实现 public class UserRepository : IUserRepository { private readonly AppDbContext _context; public UserRepository(AppDbContext context) => _context = context; public async Task<User> GetByIdAsync(int id) { return await _context.Users.FindAsync(id); } } ``` #### **3. 依赖注入配置** ```csharp // Program.cs 注册服务 builder.Services.AddScoped<IUserRepository, UserRepository>(); builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlite("Data Source=app.db")); builder.Services.AddHttpClient<IPaymentService, PaymentService>(); ``` --- ### **三、商业级最佳实践** 1. **状态管理** - 使用 `Fluxor` 或 `Blazor-State` 管理复杂应用状态 - 避免组件间直接耦合,通过事件/状态容器通信 2. **安全设计** ```csharp // 基于策略的授权 [Authorize(Policy = "AdminOnly")] public class AdminPanel : ComponentBase { ... } ``` 3. **性能优化** - 组件继承 `ComponentBase` 并重写 `ShouldRender()` - 虚拟化长列表:`<Virtualize Items="@users">` - 使用 `IAsyncDisposable` 释放资源[^4] 4. **测试策略** - 组件测试:`bUnit` 框架 - 集成测试:`Playwright` 模拟用户操作 - 单元测试:`Moq` 模拟服务依赖 --- ### **四、典型工作流示例** ```mermaid sequenceDiagram participant Browser as 浏览器 participant Component as Blazor组件 participant Service as 应用服务 participant Repository as 仓储 participant DB as 数据库 Browser->>Component: 用户操作事件 Component->>Service: 调用方法(如SubmitOrder()) Service->>Repository: 执行领域逻辑 Repository->>DB: 查询/保存数据 DB-->>Repository: 返回结果 Repository-->>Service: 返回领域对象 Service-->>Component: 返回DTO Component->>Browser: 渲染更新 ``` --- ### **五、项目模板推荐** 1. **官方模板** ```bash dotnet new blazorserver -n MyApp --auth Individual ``` 2. **企业级样板** - [CleanArchitecture Blazor](https://github.com/ardalis/CleanArchitecture):DDD+CQRS实现 - [BlazorHero](https://github.com/blazorhero/CleanArchitecture):多租户支持 --- ### **总结** 商业级 Blazor 项目应采用**分层架构**(表现层/应用层/领域层/基础设施层),结合**模块化组件设计**和**明确的责任边界**。关键要点: 1. 表现层专注UI交互,通过`@inject`解耦服务 2. 领域层封装核心业务规则,保持技术无关性 3. 基础设施层实现持久化等技术细节 4. 通过DI容器连接各层(如`AddScoped`注册仓储)[^1] 遵循此结构可提升代码可测试性(测试覆盖率>70%)、支持渐进式扩展,并便于团队协作开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逢生博客

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值