深入了解 .NET 8.0:新特性与开发最佳实践(微服务架构实践、Dapper 和 NLog 优化 .NET 应用程序的数据库操作与日志管理、控制反转与依赖注入:提升 .NET 应用程序的可维护性)

目录

1、.NET8.0

2. ASP.NET 和 ASP.NET Core 的基本概念

3. ASP.NET 与 ASP.NET Core 的区别

4. 举例说明ASP.NET Core Web API 和ASP.NET Core MVC

示例 1: ASP.NET Core Web API 示例

示例 2: ASP.NET Core MVC 示例

5.在ASP.NET Core 中开发微服务

(1)微服务架构的核心概念

(2)ASP.NET Core 微服务开发步骤

6.将现有的 ASP.NET Core项目进行微服务分解

1. 功能模块划分

2. 数据库和数据访问分离

3. API Gateway

4. 典型服务划分

5. 服务通信方式

6. 容错和重试

7. 示例划分

7.微服务之间的通信

(1)使用 HTTP 进行微服务通信

(2)使用消息队列(MQ)或 Kafka 进行微服务通信

(3)总结

8.Entity Framework Core(EF Core)

(1)定义

(2)CRUD代码实操

9. 控制反转(IoC)与依赖注入(DI)

10. Dapper

11. NLog


1、.NET8.0

.NET 8.0 是 Microsoft 发布的最新版本的跨平台开发框架,旨在支持构建现代应用程序,包括 web、桌面和云应用。它在之前版本的基础上进行了多项改进和优化,主要特点包括:

  1. 跨平台支持:允许开发者在 Windows、Linux 和 macOS 上构建和运行应用程序。

  2. 性能提升:引入了许多性能优化,提升应用的运行速度和响应能力。

  3. 统一的 API:进一步整合 .NET 生态系统,减少不同 .NET 版本间的差异。

  4. 新特性:与 C# 12 结合,增加了一些新的语法特性,提升开发效率。

  5. 更好的云集成:增强与 Azure 等云服务的集成,简化云原生应用的构建。

总体而言,.NET 8.0 为开发者提供了更强大的工具和功能,以支持现代应用开发。

2. ASP.NET 和 ASP.NET Core 的基本概念

  • ASP.NET:是微软开发的一个用于构建动态 Web 应用程序和服务的框架。它允许开发人员使用 C# 或其他 .NET 语言编写 Web 应用程序。ASP.NET 运行在 Windows 平台上,是过去广泛使用的框架。

  • ASP.NET Core:是 ASP.NET 的重新设计和升级版本,它是跨平台的(可以在 Windows、Linux 和 macOS 上运行),开源,并且比传统的 ASP.NET 更轻量级和高性能。ASP.NET Core 是用于现代 Web 开发的一个强大工具,适用于创建 Web 应用程序、RESTful API、微服务等。


3. ASP.NET 与 ASP.NET Core 的区别

  • ASP.NET:依赖于 .NET Framework,通常只能在 Windows 上运行。

  • ASP.NET Core:依赖于 .NET Core(现在已统一为 .NET 6+),可以跨平台运行,并且性能更优。


4. 举例说明ASP.NET Core Web API 和ASP.NET Core MVC

示例 1: ASP.NET Core Web API 示例

这是一个简单的 ASP.NET Core Web API 项目,处理 API 请求并返回 JSON 数据:

using Microsoft.AspNetCore.Mvc;
​
namespace WebApiExample.Controllers
{
    [ApiController]  // 声明这是一个 Web API 控制器
    [Route("api/[controller]")]  // 定义路由为 api/values
    public class ValuesController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "value1", "value2" };  // 返回 JSON 数据
        }
​
        // GET api/values/5
        [HttpGet("{id}")]
        public ActionResult<string> Get(int id)
        {
            return "value " + id;  // 根据 ID 返回具体的数据
        }
​
        // POST api/values
        [HttpPost]
        public void Post([FromBody] string value)
        {
            // 接收 POST 请求中的数据
        }
​
        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
            // 更新资源
        }
​
        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
            // 删除资源
        }
    }
}

这个例子展示了一个基本的 Web API:

  • GET 请求返回一个字符串数组,作为 JSON 响应。

  • POSTPUTDELETE 允许你发送数据到服务器,或者更新/删除数据。


示例 2: ASP.NET Core MVC 示例

这是一个简单的 ASP.NET Core MVC 示例,返回 HTML 视图:

    using Microsoft.AspNetCore.Mvc;
    //校车消息推送
    [MobileAuthorize]
    public ActionResult SchoolBusNotice(int id)
    {
        var UserId = this.User.UserId;//(用户登录后 会有自己的userID)
        var model = App.DataAccess.GetSchoolBusNoticeInfo(id, UserId);
​
        //更新阅读时间和已读状态
        App.DataAccess.UpdateNotificationReadStatus(id, UserId);
​
        return View(model);
    }

这是一个控制器动作,用于处理前端请求。

当用户访问/SchoolBusNotice/3 时候,执行一些逻辑操作(如获取数据、更新已读状态),然后返回HTML页面或视图给用户。常见于传统的Web应用程序(例如ASP.NET Core MVC),而不是用于返回JSON数据的API接口。开发接口用的框架是ASP.NET Core Web API

ASP.NET MVC中的控制器方法(ActionResult)用于处理HTTP请求并返回视图(View),这种架构属于**B/S架构

  • B/S架构是指客户端通过浏览器向服务器发送请求,服务器处理请求后,将页面(HTML、CSS、JavaScript等)返回给浏览器,浏览器负责渲染和展示内容。ASP.NET MVC正是这种典型的Web应用开发模式。浏览器是客户端,服务器是运行ASP.NET MVC应用的主机,二者通过HTTP通信。

  • 在ASP.NET MVC中,用户通过浏览器访问某个URL,发送请求到服务器,服务器的控制器方法(例如上述代码中的的SchoolBusNotice方法)会处理请求、获取数据,并生成视图(View),最终将视图渲染为HTML页面返回给浏览器进行显示。

C/S架构与B/S架构的区别:

  • C/S架构(Client/Server)是指客户端和服务器直接通信,客户端通常是一个独立的软件应用程序(如桌面程序)。客户端负责更多的业务逻辑和处理,通常需要安装在用户的本地设备上,而服务器提供后台数据和服务支持。

  • B/S架构更轻量化,客户端只需要浏览器,不需要安装额外的软件,所有的业务逻辑和处理大部分都在服务器端完成,用户通过浏览器即可访问应用程序。

5.在ASP.NET Core 中开发微服务

ASP.NET Core 中开发微服务是一种常见的架构实践,微服务架构将应用程序分解为多个独立的服务,每个服务执行特定的功能,彼此可以通过 API 通信。ASP.NET Core 是一个轻量级、高性能的框架,非常适合用于开发微服务。

(1)微服务架构的核心概念
  • 每个微服务独立部署:每个微服务都可以独立构建、部署和扩展。

  • 单一职责原则:每个微服务只负责一组相关的业务功能。

  • 跨服务通信:服务间通过 HTTP、gRPC 或消息队列通信(如 RabbitMQ、Kafka)。

  • 容错和扩展性:通过容器化(Docker、Kubernetes)来提高可扩展性和容错性。

(2)ASP.NET Core 微服务开发步骤

以下是开发微服务的一般步骤:

1.1 创建微服务项目

创建一个 ASP.NET Core 项目,每个项目对应一个独立的微服务。可以使用以下命令通过 CLI 创建 Web API 微服务:

dotnet new webapi -n ProductService

这里,ProductService 就是一个微服务,它可以提供产品相关的业务逻辑。

1.2 定义模型和控制器

为你的微服务定义模型类和控制器。

模型类 Product.cs

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

控制器类 ProductsController.cs

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private static List<Product> products = new List<Product>
    {
        new Product { Id = 1, Name = "Laptop", Price = 1200 },
        new Product { Id = 2, Name = "Phone", Price = 800 }
    };
​
    [HttpGet]
    public ActionResult<IEnumerable<Product>> Get()
    {
        return Ok(products);
    }
​
    [HttpGet("{id}")]
    public ActionResult<Product> Get(int id)
    {
        var product = products.FirstOrDefault(p => p.Id == id);
        if (product == null)
            return NotFound();
        return Ok(product);
    }
​
    [HttpPost]
    public IActionResult Post([FromBody] Product product)
    {
        products.Add(product);
        return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
    }
}

这个示例定义了一个简单的产品管理微服务,提供 RESTful API,可以获取、添加产品信息。

1.3 跨服务通信

在微服务架构中,各服务需要通信。ASP.NET Core 微服务之间可以通过以下方式通信:

  • HTTP:通过 HttpClient 发起 HTTP 请求,服务之间使用 RESTful API 进行通信。

  • gRPC:通过 gRPC 进行高性能的 RPC 调用。

  • 消息队列:使用 RabbitMQ、Kafka 等消息中间件进行异步通信。

使用 HttpClient 进行跨服务通信

public class ProductServiceClient
{
    private readonly HttpClient _httpClient;
​
    public ProductServiceClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
​
    public async Task<Product> GetProductAsync(int id)
    {
        var response = await _httpClient.GetAsync($"http://productservice/api/products/{id}");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsAsync<Product>();
    }
}

1.4 服务发现

微服务在大规模部署时可能会动态扩展或重启,导致 IP 地址变化。服务发现可以通过 ConsulEureka 等工具来管理服务实例。

使用 Consul 进行服务发现的一个示例:

  1. 启动 Consul 服务。

  2. 每个微服务启动时在 Consul 中注册自己。

  3. 通过 Consul 查找其他微服务的地址。

在 ASP.NET Core 中,可以通过 HttpClient 工厂与 Consul 集成,动态发现服务。

1.5 容错和重试机制

微服务之间通信时,网络不稳定或服务不可用可能导致请求失败。为了提升稳定性,你可以使用容错和重试机制。

  • Polly 是一个容错和重试库,ASP.NET Core 提供了与 Polly 的集成,可以轻松添加重试、断路器等机制。

使用 Polly 添加重试策略

services.AddHttpClient<ProductServiceClient>()
    .AddTransientHttpErrorPolicy(policy => policy.RetryAsync(3));  // 3 次重试

1.6 容器化微服务

为了更好地部署和管理微服务,通常将微服务容器化。

  1. 创建 Dockerfile: 在项目根目录下创建一个 Dockerfile,用于将微服务容器化:

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
​
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet build -c Release -o /app/build
​
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
​
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProductService.dll"]
  1. 构建和运行 Docker 镜像

docker build -t productservice .
docker run -d -p 8080:80 productservice

1.7 使用 Kubernetes 管理微服务

Kubernetes 是一个流行的容器编排工具,可以帮助管理容器化的微服务。

(1)创建 Kubernetes 部署文件 deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: productservice
spec:
  replicas: 3
  selector:
    matchLabels:
      app: productservice
  template:
    metadata:
      labels:
        app: productservice
    spec:
      containers:
      - name: productservice
        image: productservice:latest
        ports:
        - containerPort: 80

(2)部署到 Kubernetes:

kubectl apply -f deployment.yaml

通过 Kubernetes,可以轻松实现自动扩展、负载均衡和容错。

6.将现有的 ASP.NET Core项目进行微服务分解

要将现有的 ASP.NET Core项目分解为多个独立的微服务,首先需要了解该项目中的功能模块和业务逻辑。每个模块或服务都应单独处理某个特定的职责,并能独立开发、部署和扩展。你可以考虑以下几个方面来划分微服务:

1. 功能模块划分

根据项目的业务逻辑,识别出可以单独处理的功能模块。常见的模块包括:

  • 用户管理服务:负责处理用户的注册、登录、权限管理等操作。

  • 通知服务:处理系统中的通知(如校车推送、公告等)。

  • 学生信息管理服务:负责处理与学生相关的数据(如学生信息、成绩、课程等)。

  • 家长服务:管理家长相关的信息和操作,如与子女关联、查看信息等。

  • 微信通知服务:处理微信的消息和模板通知功能。

2. 数据库和数据访问分离

每个微服务应拥有自己的数据库或数据存储,这样可以确保服务之间的独立性。可以将与学生、通知、家长等不同业务领域相关的数据库分离。例如:

  • 用户数据库:存储用户的登录信息、角色、权限等。

  • 学生数据库:存储学生个人信息、学业记录等。

  • 通知数据库:存储系统通知信息,如公告、推送记录。

3. API Gateway

使用 API 网关作为入口点,协调多个微服务的请求。API 网关的功能包括:

  • 路由外部请求到相应的微服务。

  • 负载均衡、限流等操作。

  • 在复杂应用中,可以集成认证、缓存等功能。

4. 典型服务划分

根据你的项目架构,可以考虑以下服务划分:

  • 用户认证服务(Authentication Service): 处理所有与用户认证相关的操作,包括登录、注册、授权。此服务独立于其他功能模块,可以通过 OAuth 或 JWT 进行用户身份验证。

  • 校车推送服务(Bus Notification Service): 专门处理校车的通知和推送功能,独立的推送逻辑可以让服务灵活扩展或与外部服务(如微信通知)集成。

  • 消息服务(Message Service): 处理系统的消息通知,包含微信消息、校内公告等。你当前项目中涉及到大量通知和消息逻辑,完全可以拆分为一个独立的服务。

  • 学生信息管理服务(Student Info Service): 处理学生的基本信息、学籍管理和课程安排等。任何需要与学生相关的数据操作都会通过该服务来执行。

5. 服务通信方式
  • 同步通信:可以使用 HTTP 或 gRPC 协议,确保服务之间快速通信。适合需要及时响应的场景。

  • 异步通信:对于不需要即时反馈的操作,可以使用消息队列(如 RabbitMQ 或 Kafka)来实现异步通信。适合任务队列、通知推送等操作。

6. 容错和重试

为了确保系统的稳定性,在微服务间调用时可以使用像 Polly 这样的库来实现重试和容错策略,以应对网络不稳定或服务暂时不可用的情况。

7. 示例划分
  • 用户服务:负责用户登录、身份验证、权限管理。

  • 通知服务:处理各种通知,如微信推送、短信等。

  • 学生管理服务:管理学生的基本信息和学籍相关功能。

  • 家长服务:专注于家长与学生的关系维护,查看信息等功能。

  • 日志服务:处理系统日志记录和分析。

7.微服务之间的通信

(1)使用 HTTP 进行微服务通信

假设有一个用户服务和一个学生信息管理服务。用户服务需要验证用户身份后才能获取学生信息。

  1. 用户服务:

    • 提供一个登录接口:

      POST /api/auth/login
    • 登录成功后返回一个 JWT 令牌。

  2. 学生信息管理服务

    • 提供一个获取学生信息的接口:

      GET /api/students/{studentId}
    • 用户服务在调用学生服务时,会在请求头中附加 JWT 令牌进行身份验证。

(2)使用消息队列(MQ)或 Kafka 进行微服务通信

在使用消息队列或 Kafka 时,服务之间的通信通常是异步的,适合处理不需要立即响应的场景。

  1. 示例场景:

    • 当用户注册后,用户服务会向消息队列发送一个注册成功的消息,通知其他服务(如通知服务)。

  2. 用户服务:

    • 发布消息:

      // 使用 RabbitMQ 作为示例
      var message = new { UserId = user.Id, Message = "User registered." };
      var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message));
      channel.BasicPublish(exchange: "", routingKey: "user-registered", body: body);
  3. 通知服务

    • 监听消息:

      // 从 RabbitMQ 消费者获取消息
      var consumer = new EventingBasicConsumer(channel);
      consumer.Received += (model, ea) =>
      {
          var body = ea.Body.ToArray();
          var message = JsonConvert.DeserializeObject<Message>(Encoding.UTF8.GetString(body));
          // 处理通知逻辑
      };
      channel.BasicConsume(queue: "user-registered", autoAck: true, consumer: consumer);
(3)总结
  • HTTP:适合需要实时交互的场景,通过 RESTful API 或 gRPC 进行服务调用。

  • 消息队列/Kafka:适合异步处理的场景,服务通过发布/订阅模型进行通信,解耦服务之间的依赖。

8.Entity Framework Core(EF Core)

(1)定义

Entity Framework Core(EF Core)是 Microsoft 开发的一个轻量级、跨平台的对象关系映射(ORM)框架,旨在简化 .NET 应用程序与数据库之间的交互。EF Core 允许开发者使用 .NET 对象操作数据库,而无需直接处理 SQL 语句。

主要特点包括:

  1. 跨平台支持:可以在 Windows、Linux 和 macOS 上使用。

  2. 灵活的数据库支持:支持多种数据库,包括 SQL Server、SQLite、PostgreSQL 和 MySQL 等。

  3. LINQ 查询:使用 LINQ(语言集成查询)来构建数据库查询,提供更强的类型安全和可读性。

  4. 代码优先和数据库优先:支持通过代码定义模型(代码优先)或从现有数据库生成模型(数据库优先)。

  5. 迁移支持:提供数据库迁移功能,方便管理数据库架构的演变。

EF Core 使得开发者能够更高效地进行数据访问和管理,提升了开发效率和代码可维护性。

(2)CRUD代码实操

1. 创建模型

创建一个简单的 Student 类,作为数据库模型。

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

2. 创建数据库上下文

创建一个 SchoolContext 类,继承自 DbContext

using Microsoft.EntityFrameworkCore;
​
public class SchoolContext : DbContext
{
    public DbSet<Student> Students { get; set; }
​
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("YourConnectionStringHere");
    }
}

3. CRUD 操作示例

以下是一个简单的示例,展示如何进行基本的 CRUD 操作:

using (var context = new SchoolContext())
{
    // 创建
    var student = new Student { Name = "Alice", Age = 21 };
    context.Students.Add(student);
    context.SaveChanges();
​
    // 读取
    var students = context.Students.ToList();
    
    // 更新
    var studentToUpdate = context.Students.First();
    studentToUpdate.Age = 22;
    context.SaveChanges();
​
    // 删除
    var studentToDelete = context.Students.First();
    context.Students.Remove(studentToDelete);
    context.SaveChanges();
}

9. 控制反转(IoC)与依赖注入(DI)

(1)控制反转(IoC) 是一种设计原则,指的是将对象的控制权反转给外部容器,而不是由对象自身管理其依赖。这样可以降低组件之间的耦合度,提高灵活性和可维护性。

(2)依赖注入(DI) 是实现 IoC 的一种具体方式。通过 DI,可以将所需的依赖项以参数的形式注入到类中,而不是在类内部创建这些依赖项。

(3)不使用 DI 的代码示例:

public class PathPlanner
{
    private readonly Logger _logger;
​
    public PathPlanner()
    {
        _logger = new Logger(); // 直接创建依赖
    }
​
    public void PlanPath()
    {
        _logger.Log("Planning path...");
        // 其他逻辑
    }
}

使用 DI 的代码示例

public class PathPlanner
{
    private readonly ILogger _logger;
​
    // 通过构造函数注入依赖
    public PathPlanner(ILogger logger)
    {
        _logger = logger;
    }
​
    public void PlanPath()
    {
        _logger.Log("Planning path...");
        // 其他逻辑
    }
}

在使用 DI 时,可以使用依赖注入容器(如 Microsoft.Extensions.DependencyInjection)来管理这些依赖项。

10. Dapper

Dapper 是一个轻量级的对象关系映射(ORM)库,用于在 .NET 应用程序中简化数据库操作。它通过简单的 SQL 查询实现快速的数据访问,同时保持较高的性能。

示例

假设要在校车线路规划中从数据库获取一些线路数据,可以使用 Dapper 这样做:

using (var connection = new SqlConnection("YourConnectionString"))
{
    connection.Open();
    var sql = "SELECT * FROM Paths WHERE Id = @Id";
    var path = connection.QuerySingle<Path>(sql, new { Id = pathId });
}

Dapper 使得从数据库中查询数据变得简单而高效,尤其适合对性能有较高要求的场景。

11. NLog

NLog 是一个用于 .NET 应用程序的日志框架,支持多种日志目标(如文件、数据库、控制台等)和灵活的配置。它允许记录应用程序的运行时信息,以便于调试和监控。

示例

在你的车辆路径规划模型中,你可以使用 NLog 来记录日志:

private static readonly Logger logger = LogManager.GetCurrentClassLogger();
​
public void PlanPath()
{
    logger.Info("Starting path planning...");
    // 其他逻辑
    logger.Info("Path planning completed.");
}

你需要在项目中配置 NLog,以指定日志输出的目标和格式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值