LyuExtensions 1.1.10

dotnet add package LyuExtensions --version 1.1.10
                    
NuGet\Install-Package LyuExtensions -Version 1.1.10
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="LyuExtensions" Version="1.1.10" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LyuExtensions" Version="1.1.10" />
                    
Directory.Packages.props
<PackageReference Include="LyuExtensions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add LyuExtensions --version 1.1.10
                    
#r "nuget: LyuExtensions, 1.1.10"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package LyuExtensions@1.1.10
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=LyuExtensions&version=1.1.10
                    
Install as a Cake Addin
#tool nuget:?package=LyuExtensions&version=1.1.10
                    
Install as a Cake Tool

LyuExtensions

NuGet GitHub

一个聚焦日常开发场景的 .NET 扩展库,提供 AOP 特性和扩展方法,助力快速构建业务代码。

目录


AOP 特性

基于 Metalama 框架的 AOP 特性,通过简单的特性标注实现横切关注点。

TryCatchAttribute - 自动异常处理

自动为方法添加 try-catch 包装,捕获异常、记录日志并返回默认值,无需手动编写异常处理代码。

使用示例

基础使用 - 自动捕获异常并记录日志:

[TryCatch]
public string? GetUserName(int userId)
{
    // 如果出现异常,会自动记录日志并返回 null
    return database.Query("SELECT name FROM users WHERE id = " + userId);
}

// 调用时不需要 try-catch
var name = GetUserName(123); // 异常时返回 null

指定默认返回值:

[TryCatch(DefaultValue = "Unknown")]
public string GetUserName(int userId)
{
    // 如果出现异常,返回 "Unknown"
    return database.Query("SELECT name FROM users WHERE id = " + userId);
}

[TryCatch(DefaultValue = 0)]
public int CalculateTotal(List<int> numbers)
{
    // 如果出现异常,返回 0
    return numbers.Sum();
}

[TryCatch(DefaultValue = false)]
public bool ValidateData(string data)
{
    // 如果出现异常,返回 false
    return data.Length > 0 && data.Contains("valid");
}

TimingAttribute - 方法耗时统计

自动统计方法执行耗时,支持自定义日志级别记录。

使用示例

基础使用 - 默认 Information 级别记录日志:

[Timing]
public async Task ProcessData()
{
    await Task.Delay(1000);
    // 业务逻辑
}

// 日志输出 (Information): 方法执行完成: YourNamespace.YourClass.ProcessData, 耗时: 1002ms

自定义日志级别:

// 使用 Debug 级别记录
[Timing(LogLevelValue = 1)]
public void Calculate()
{
    // 复杂计算
}

// 使用 Warning 级别记录
[Timing(LogLevelValue = 3)]
public void ImportantOperation()
{
    // 重要操作
}

// 不记录日志 (None)
[Timing(LogLevelValue = 6)]
public void QuietOperation()
{
    // 不会记录任何日志
}

异常处理:

[Timing]
public void RiskyOperation()
{
    throw new Exception("出错了");
}

// 即使抛出异常,也会记录耗时(使用 Error 级别)
// 日志输出: 方法执行异常: YourNamespace.YourClass.RiskyOperation, 耗时: 5ms
// 异常会被重新抛出

异步方法支持:

[Timing]
public async Task<List<User>> GetUsersAsync()
{
    return await httpClient.GetFromJsonAsync<List<User>>("api/users");
}

// 日志输出: 方法执行完成: YourNamespace.YourClass.GetUsersAsync, 耗时: 234ms
日志级别说明
LogLevelValue 日志级别 说明
0 Trace 最详细的日志
1 Debug 调试信息
2 Information 常规信息(默认)
3 Warning 警告信息
4 Error 错误信息
5 Critical 严重错误
6 None 不记录日志
属性说明
属性 类型 默认值 说明
LogLevelValue int 2 日志记录级别,默认为 Information
注意事项
  • 异常发生时会使用 Error 级别记录日志,并重新抛出异常
  • 日志通过依赖注入的 ILogger 记录,确保已配置日志服务
  • 设置 LogLevelValue = 6 可以完全禁用日志记录

ServiceAttribute - 自动 DI 注册

通过特性标注自动注册服务到 DI 容器,告别繁琐的手动注册。

特性列表
  • [Singleton] - 注册为单例服务
  • [Scoped] - 注册为作用域服务
  • [Transient] - 注册为瞬态服务
  • [HostedService] - 注册为后台服务
使用示例

1. 标记服务类:

// 注册为单例
[Singleton]
public class CacheService
{
    public void Set(string key, object value) { }
    public object Get(string key) { return null; }
}

// 注册为作用域服务
[Scoped]
public class OrderService
{
    public void CreateOrder() { }
}

// 注册为瞬态服务
[Transient]
public class EmailSender
{
    public void Send(string to, string subject) { }
}

// 注册为后台服务
[HostedService]
public class DataSyncService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            // 后台任务逻辑
            await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
        }
    }
}

2. 注册接口实现:

public interface IUserService
{
    void CreateUser(string name);
}

[Singleton(ServiceType = typeof(IUserService))]
public class UserService : IUserService
{
    public void CreateUser(string name) { }
}

// 使用时注入接口
public class UserController
{
    private readonly IUserService _userService;
    
    public UserController(IUserService userService)
    {
        _userService = userService;
    }
}

3. 多实现场景 - 使用 ServiceKey:

public interface IPaymentProvider
{
    void Pay(decimal amount);
}

[Singleton(ServiceType = typeof(IPaymentProvider), ServiceKey = "Alipay")]
public class AlipayProvider : IPaymentProvider
{
    public void Pay(decimal amount) { }
}

[Singleton(ServiceType = typeof(IPaymentProvider), ServiceKey = "WeChat")]
public class WeChatPayProvider : IPaymentProvider
{
    public void Pay(decimal amount) { }
}

// 使用时通过 Key 注入
public class PaymentService
{
    private readonly IPaymentProvider _alipay;
    private readonly IPaymentProvider _wechat;
    
    public PaymentService(
        [FromKeyedServices("Alipay")] IPaymentProvider alipay,
        [FromKeyedServices("WeChat")] IPaymentProvider wechat)
    {
        _alipay = alipay;
        _wechat = wechat;
    }
}

4. 在 Program.cs 中注册:

using LyuExtensions.Aspects;

var builder = WebApplication.CreateBuilder(args);

// 扫描并注册当前程序集中所有带特性的服务
builder.Services.RegisterServices();

// 或者扫描指定程序集
builder.Services.RegisterServices(typeof(UserService).Assembly);

// 或者扫描多个程序集
builder.Services.RegisterServices(
    typeof(UserService).Assembly,
    typeof(OrderService).Assembly
);

var app = builder.Build();
app.Run();

Observable - 自动属性通知

基于 Metalama.Patterns.Observability 的自动属性变更通知

特性
  • 自动实现 INotifyPropertyChanged 接口
  • 自动为所有属性生成 PropertyChanged 事件
  • 支持依赖属性自动通知

Inject - 自动注入

 [Inject]
 private readonly ILogger<MainViewModel> _logger;

自动将日志注入到当前实例,前提是双方都已注入