从"Hello World"到高手进阶:10个必掌握的.NET Core实战技巧

作者:微信公众号:【架构师老卢】
6-7 9:3
13

你已经告别了"Hello World"阶段,能比泡方便面还快地搭建API,但总觉得哪里不对劲...仿佛每次生产环境出问题(本地却正常)时,框架都在无声地嘲笑你。是的,是时候升级了。

  1. 依赖注入(DI) —— 不只是流行词 我知道你用过了——可能从StackOverflow复制来的。也许注入过一两个DbContext。但真正理解DI?这才是区分中级和高级开发者的关键。

DI帮你写出可测试、可维护、低耦合的代码。它还能防止服务之间像离不开充电器的朋友那样紧密依赖。

.NET依赖注入:该用内置DI还是自研? 有没有在Startup.cs配置服务时,两小时后发现自己深陷作用域不匹配和内存泄漏的泥潭... levelup.gitconnected.com

想象雇佣自带工具的水管工 vs 需要你现买工具的。后者就是紧耦合代码。别做那种人。

步骤1:创建服务接口与实现

public interface IGreetingService
{
    string GetGreeting(string name);
}

public class GreetingService : IGreetingService
{
    public string GetGreeting(string name)
    {
        return $"你好, {name}! 祝你编码高效。";
    }
}

步骤2:在Program.cs注册服务

builder.Services.AddScoped<IGreetingService, GreetingService>();

步骤3:在控制器中注入使用

public class HomeController : Controller
{
    private readonly IGreetingService _greetingService;

    public HomeController(IGreetingService greetingService)
    {
        _greetingService = greetingService;
    }

    public IActionResult Index()
    {
        var message = _greetingService.GetGreeting("开发者");
        return Content(message);
    }
}

现在这个控制器不关心谁提供问候语,实现了松耦合和可测试性。

  1. 中间件 —— 应用的守门人 中间件就像夜店门口严格筛选访客的保安,决定谁可以进入,谁该收到401。每个请求都要经过中间件管道。

自定义中间件(RequestLoggerMiddleware.cs):

public class RequestLoggerMiddleware
{
    private readonly RequestDelegate _next;

    public RequestLoggerMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine($"[请求] {context.Request.Method} {context.Request.Path}");
        await _next(context);
        Console.WriteLine($"[响应] {context.Response.StatusCode}");
    }
}

在Program.cs注册:

app.UseMiddleware<RequestLoggerMiddleware>();
  1. 配置与密钥 —— 请停止硬编码 我们都干过——直接把连接字符串扔进appsettings.json。但当应用扩展时,你需要更聪明的做法。

关键工具:

  • IConfiguration
  • 用户密钥(本地开发)
  • Azure密钥保管库(生产环境)

你会把ATM密码写在银行卡上吗?那为何要用明文存数据库密码?

步骤1:appsettings.json

{
  "MyAppSettings": {
    "SupportEmail": "support@yourapp.com"
  }
}

步骤2:创建强类型类

public class MyAppSettings
{
    public string SupportEmail { get; set; }
}

步骤3:绑定并注入

// Program.cs
builder.Services.Configure<MyAppSettings>(
    builder.Configuration.GetSection("MyAppSettings"));
  1. 异步编程 —— 不仅要会用,更要懂原理 你可能见过async Task,甚至复制过await语句。但如果不懂原理,可能会严重损害性能。

模拟异步调用的服务:

public interface IJokeService
{
    Task<string> GetRandomJokeAsync();
}

public class JokeService : IJokeService
{
    public async Task<string> GetRandomJokeAsync()
    {
        await Task.Delay(1000); // 模拟I/O延迟
        return "为什么程序员喜欢黑暗模式?因为光亮会吸引bug!";
    }
}
  1. Entity Framework Core —— 不只是CRUD EF Core将C#类映射到数据库表,但远不止.ToList()和.Add()。

实体模型:

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
    public bool IsAvailable { get; set; }
}

DbContext:

public class AppDbContext : DbContext
{
    public DbSet<Book> Books { get; set; }

    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
}
  1. 日志记录 —— 未来的你会感谢现在 .NET Core的日志记录帮助追踪应用流程、捕获错误,支持结构化日志和多种日志提供程序。
public class OrderService
{
    private readonly ILogger<OrderService> _logger;

    public OrderService(ILogger<OrderService> logger)
    {
        _logger = logger;
    }

    public void PlaceOrder(int userId)
    {
        _logger.LogInformation("正在为用户{UserId}下单,时间:{Time}", userId, DateTime.UtcNow);
        // ...
    }
}
  1. 最小API —— 轻量级HTTP解决方案 .NET 6+的最小API无需完整MVC栈即可构建轻量HTTP API。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/weather/{city}", (string city, IWeatherService weatherService) =>
{
    var forecast = weatherService.GetForecast(city);
    return Results.Ok(forecast);
});

app.Run();
  1. 后台服务 —— 非所有任务都需控制器 使用IHostedService和BackgroundService处理独立于HTTP请求的任务。
public class EmailReminderService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
        }
    }
}
  1. 异常处理 —— 因为系统总会出错 全局异常处理器:
app.UseExceptionHandler(errorApp =>
{
    errorApp.Run(async context =>
    {
        context.Response.StatusCode = 500;
        await context.Response.WriteAsJsonAsync(new { message = "出错了" });
    });
});
  1. 性能分析 —— 你的应用很快...直到变慢 使用内存缓存:
public decimal GetUsdToInrRate()
{
    return _cache.GetOrCreate("USD_INR_RATE", entry =>
    {
        entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30);
        return 83.50m;
    });
}

总结:现在怎么做? 这10个概念只是冰山一角。要真正掌握它们:

  • 阅读文档
  • 在副业项目中试错
  • 用新模式重构旧代码
  • 多问"为什么"而非"怎么做"

因为会写.AddScoped()是一回事,而理解其作用域原理、使用场景及对内存性能的影响——这才是精通的开始。

继续构建,继续突破,持续学习。如果本文有帮助,分享给还在硬编码配置密钥的同事吧——他们正需要这个。

相关留言评论
昵称:
邮箱:
阅读排行