4

面向接口编程实践之aspnetcoreapi的抽象 - 星仔007

 1 year ago
source link: https://www.cnblogs.com/morec/p/17330706.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

面向接口编程实践之aspnetcoreapi的抽象

最为一名越过菜鸟之后的开发,需要做接口开发。下面做一个纯粹的接口编程的实例demo,仅仅是一个webapi接口的抽象。

下面是代码接口,AbsEFWork是webapi,BaseEntityFramework是一个接口库。

1099890-20230418180829301-755854732.png

先介绍一下webapi的实现,代码是从底层往上层写的,阅读代码的习惯应该是自上向下。

 public class ProductController : CustomController<Product>
    {
        public ProductController(IEFCoreService<Product> efCoreService) : base(efCoreService)
        {
        }
    }

控制器代码很简单的实现了CustomController,数据载体是Product。

using BaseEntityFramework.Implementations;
using BaseEntityFramework.Implementations.Entitys;
using BaseEntityFramework.IService;
using Microsoft.EntityFrameworkCore;

namespace BaseEntityFramework
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();
            builder.Services.AddDbContext<ProductDbContext>(options => options.UseInMemoryDatabase("memorydb"));
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
            builder.Services.AddScoped<IEFCoreService<Product>, EFCoreProductService>();
            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            app.UseHttpsRedirection();

            app.UseAuthorization();


            app.MapControllers();

            app.Run();
        }
    }
}

Program启动程序需要实现IEFCoreService的注入,以及ProductDbContext 的内存实现。

这样就可以启动一个swagger

1099890-20230418181429157-1421748344.png

对于product数据存储的具体实现,实体类product和dbcontext必须要自己去实现它。

 public class Product:IEntity
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }

        [Column(TypeName = "decimal(28,16)")]
        public decimal Price { get; set; }
    }
using BaseEntityFramework.Implementations.Entitys;
using Microsoft.EntityFrameworkCore;

namespace BaseEntityFramework.Implementations
{
    public class ProductDbContext:DbContext
    {
        public ProductDbContext(DbContextOptions<ProductDbContext> dbContextOptions):base(dbContextOptions)
        {

        } 
        public DbSet<Product> Products { get; set; }
    }
}

查看上面的控制器代码,有注入IEFCoreService<Product>的业务代码,对于接口肯定是需要一个实现,这里可以再次封装一个抽象的基类来(温馨提示:重复的代码,必须优化),我这里暂时没做处理。

using BaseEntityFramework.Implementations.Entitys;
using BaseEntityFramework.IService;
using BaseEntityFramework.Models;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;

namespace BaseEntityFramework.Implementations
{
    public class EFCoreProductService : IEFCoreService<Product>
    {
        private readonly ProductDbContext _dbContext;
        public EFCoreProductService(ProductDbContext productDbContext)
        {
            _dbContext = productDbContext;
        }

        public async Task<bool> Add(Product entity)
        {
            _dbContext.Products.Add(entity);
            var result = await _dbContext.SaveChangesAsync();
            return result != 0;
        }

        public Task<bool> Delete(Product entity)
        {
            throw new NotImplementedException();
        }

        public async Task<IEnumerable<Product>> GetAll()
        {
            var result =await _dbContext.Products.ToListAsync();
            return result;
        }

        public Task<Product> GetEntity(Expression<Func<Product, bool>> expression)
        {
            throw new NotImplementedException();
        }

        public async Task<IReadOnlyCollection<Product>> GetList(Expression<Func<Product, bool>> expression)
        {
            var result = await _dbContext.Products.Where(expression).ToListAsync();
            return result.AsReadOnly();
        }

        public Task<PageResult<Product>> GetPageResult<Req>(PageInput<Req> pagInput) where Req : new()
        {
            throw new NotImplementedException();
        }

        public Task<bool> Update(Product entity)
        {
            throw new NotImplementedException();
        }
    }
}

上面的代码很简单易懂,最大的好处就是可以复用。实体类和 dbcontext越多这个简简单单的结构就越是有用。

BaseEntityFramework的核心逻辑就是把业务代码做了抽象,做了一个统一的模板,不管 是从那方便说都只有好处。而且作为开发只关心自己的业务代码这一块。

 public interface IEFCoreService<T> where T:IEntity
    {
        Task<bool> Add(T entity) ;
        Task<bool> Delete(T entity);
        Task<bool> Update(T entity);
        Task<IReadOnlyCollection<T>> GetList(Expression<Func<T,bool>> expression) ;
        Task<PageResult<T>> GetPageResult<Req>(PageInput<Req> pagInput) where Req:new();
        Task<T> GetEntity(Expression<Func<T, bool>> expression);
        Task<IEnumerable<T>> GetAll();
    }

以上的实例只是一个简单的demo,项目中需要做框架的话这或许是一个开始,需要做的远远不止这些。

liuzhixin405/AbsEFWork (github.com)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK