【ASP.NET CORE】1. 基础搭建

架构

图片[1]-【ASP.NET CORE】1. 基础搭建-涣清博客

Application

主要编写WebApi 依赖Service层

提供一个基类,自动路由API

using Microsoft.AspNetCore.Mvc;

namespace WebApplication.Application.Base;
[ApiController]
[Route("api/[controller]")]
public abstract class ApiControllerBase : ControllerBase
{
    protected IActionResult ApiResponse<T>(T data)
    {
        return Ok(new { success = true, data });
    }

    protected IActionResult ApiError(string message)
    {
        return BadRequest(new { success = false, error = message });
    }
}

使用如下

using HQ.Entity.Model;
using HQ.Service.Interface;
using Microsoft.AspNetCore.Mvc;
using WebApplication.Application.Base;

namespace WebApplication.Application;

public class UserServiceApplication : ApiControllerBase
{
    private readonly IUserService _userService;

    public UserServiceApplication(IUserService userService)
    {
        _userService = userService;
    }
    [HttpPost]
    public async Task<List<User>> GetListAsync()
    {
        return await _userService.GetListAsync();
    }
}

Common层

主要用于编写系统核心库,目前实现了ORM及依赖注入,后续继续完善

ORM

实体基类

namespace HQ.Common.ORM.SQLSugar;

/// <summary>
/// 实体基类
/// </summary>
public class BaseEntity<TKey>
{
    public TKey Id { get; set; }
}

public class BaseEntity : BaseEntity<int> { }

仓储基类

using SqlSugar;

namespace HQ.Common.ORM.SQLSugar;

public class BaseRepository<T, TKey> : IBaseRepository<T, TKey> where T : BaseEntity<TKey>, new()
{
    protected ISqlSugarClient _db;

    public BaseRepository(ISqlSugarClient db)
    {
        _db = db;
    }

    public async Task<List<T>> GetListAsync()
    {
        return await _db.Queryable<T>().ToListAsync();
    }

    public async Task<T> GetByIdAsync(TKey id)
    {
        return await _db.Queryable<T>().FirstAsync(x => x.Id.Equals(id));
    }

    public async Task<bool> AddAsync(T entity)
    {
        return await _db.Insertable(entity).ExecuteCommandAsync() > 0;
    }

    public async Task<bool> AddRangeAsync(List<T> entities)
    {
        return await _db.Insertable(entities).ExecuteCommandAsync() > 0;
    }

    public async Task<bool> UpdateAsync(T entity)
    {
        return await _db.Updateable(entity).ExecuteCommandAsync() > 0;
    }

    public async Task<bool> DeleteAsync(TKey id)
    {
        return await _db.Deleteable<T>().Where(x => x.Id.Equals(id)).ExecuteCommandAsync() > 0;
    }

    public async Task<bool> DeleteAsync(T entity)
    {
        return await _db.Deleteable(entity).ExecuteCommandAsync() > 0;
    }

    public async Task<int> CountAsync()
    {
        return await _db.Queryable<T>().CountAsync();
    }

    public async Task<bool> ExistsAsync(TKey id)
    {
        return await _db.Queryable<T>().AnyAsync(x => x.Id.Equals(id));
    }
}

仓储接口

namespace HQ.Common.ORM.SQLSugar;

public interface IBaseRepository<T, TKey> where T : BaseEntity<TKey>, new()
{
    Task<List<T>> GetListAsync();
    Task<T> GetByIdAsync(TKey id);
    Task<bool> AddAsync(T entity);
    Task<bool> AddRangeAsync(List<T> entities);
    Task<bool> UpdateAsync(T entity);
    Task<bool> DeleteAsync(TKey id);
    Task<bool> DeleteAsync(T entity);
    Task<int> CountAsync();
    Task<bool> ExistsAsync(TKey id);
}

DI

自定义Service特性

using Microsoft.Extensions.DependencyInjection;

namespace HQ.Common.DI;

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class ServiceAttribute : Attribute
{
    public ServiceLifetime Lifetime { get; }
    public Type? ServiceType { get; }

    public ServiceAttribute(ServiceLifetime lifetime = ServiceLifetime.Scoped)
    {
        Lifetime = lifetime;
    }
}

作用

  • 这是一个标记特性,用来给业务类打标签
  • 告诉自动注册工具:这个类要注册到 DI 容器
  • 可以指定生命周期(默认 Scoped)
  • 可以手动指定服务类型(接口)
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;

namespace HQ.Common.DI;

public static class ServiceRegistration
{
    public static IServiceCollection AddHQServices(
        this IServiceCollection services,
        params Assembly[] assemblies)
    {
        if (assemblies.Length == 0)
        {
            assemblies = new[] { Assembly.GetCallingAssembly() };
        }

        // 手动扫描注册(支持自定义 ServiceType)
        var types = assemblies
            .SelectMany(a => a.GetTypes())
            .Where(t => t.IsClass && !t.IsAbstract)
            .Select(t => new { Type = t, Attr = t.GetCustomAttribute<ServiceAttribute>() })
            .Where(x => x.Attr != null);

        foreach (var item in types)
        {
            var impl = item.Type;
            var attr = item.Attr!;

            var service = attr.ServiceType 
                          ?? impl.GetInterfaces().FirstOrDefault() 
                          ?? impl;

            services.Add(new ServiceDescriptor(service, impl, attr.Lifetime));
        }

        return services;
    }

    // 保留 Scrutor 的装饰器扩展
    public static IServiceCollection DecorateHQ<TService, TDecorator>(
        this IServiceCollection services) where TDecorator : TService
    {
        return services.Decorate<TService, TDecorator>();
    }
}

核心逻辑

  1. 自动扫描:遍历传入的程序集,查找带[Service]的非抽象类
  2. 自动匹配服务类型
    • 优先用特性里手动指定的接口
    • 没有就用类实现的第一个接口
    • 都没有就注册自身
  3. 自动注册:按照特性指定的生命周期注册到微软 DI 容器
  4. 兼容装饰器:保留了 Scrutor 库的装饰器功能

配置

builder.Services.AddHQServices(typeof(IServiceMarker).Assembly);

Service层放入一个空接口IServiceMarker用于标记

使用装饰器

// 装饰器类
public class UserServiceDecorator : IUserService
{
    private readonly IUserService _innerService;
    public UserServiceDecorator(IUserService innerService) => _innerService = innerService;

    public void GetUser()
    {
        Console.WriteLine("装饰器前置逻辑");
        _innerService.GetUser();
        Console.WriteLine("装饰器后置逻辑");
    }
}

// Program.cs 注册装饰器
builder.Services.AddHQServices();
builder.Services.DecorateHQ<IUserService, UserServiceDecorator>();
写法注册结果生命周期
[Service]接口 → 实现类Scoped(默认)
[Service(ServiceLifetime.Singleton)]接口 → 实现类单例
[Service(ServiceLifetime.Transient)]接口 → 实现类瞬时
[Service(ServiceType = typeof(IMyService))]指定接口 → 实现类按配置
类没有实现接口 [Service]自身 → 自身按配置

Entity层

该层主要编写DTO及Model

数据库实体示例

using HQ.Common.ORM.SQLSugar;
using SqlSugar;

namespace HQ.Entity.Model;

[SugarTable("Users")]
public class User : BaseEntity<string>
{
    public string UserName { get; set; }
    public string Email { get; set; }
}

Service层

该层主要编写业务代码

分Interface文件夹及service文件夹

using HQ.Entity.Model;

namespace HQ.Service.Interface;

public interface IUserService
{
    public Task<List<User>> GetListAsync();

}

使用[Service(ServiceLifetime.Scoped)]自动注册

using HQ.Common.DI;
using HQ.Service.Interface;
using Microsoft.Extensions.DependencyInjection;
using HQ.Common.ORM.SQLSugar;
using HQ.Entity.Model;

namespace HQ.Service.Service;
[Service(ServiceLifetime.Scoped)]
public class UserService : IUserService
{
    private readonly IBaseRepository<User,string> _repo;

    public UserService(IBaseRepository<User, string> repo)
    {
        _repo = repo;
    }

    public async Task<List<User>> GetListAsync()
    {
        return await _repo.GetListAsync();
    }

}
© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容