开始前的准备
创建Asp.Net Core Web Api项目
如果勾选启用Docker会生成相应的Dockerfile文件,勾选Use controllers 表示我们创建的Web Api项目带有Controller,不勾选的话是MinimApi ,它是在Program.cs 中以goes to运行,为了性能而生。这里我们用的DotNet7 。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/b112dcba0d7f4f8e8f6cb5393b581b29.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
项目介绍
OK,创建好了项目之后我们会发现与以往的.NET5、.NET Core 不太一样,我们稍微介绍下每个文件的作用。
![在这里插入图片描述](https://img-blog.csdnimg.cn/59957668ed644572853ed5d87d142b91.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
Properties 文件夹下的launchSettings.json 文件:
配置IIS、Swagger、项目启动的端口等功能。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/a45febd6f00f4c74ba6148fd2da3277e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
Controllers 文件夹就不用做过多解释了吧,我们看看自带的WeatherForecastController.cs 文件。
我们可以看到有个构造函数 _logger,与以往的New()不一样,这个是构造函数注入进来的,从.NET5还是core之后自带IOC容器。待会我们将自带的IOC改成Autofac。
![在这里插入图片描述](https://img-blog.csdnimg.cn/bff39357a0bf4b2b95563dc85ad56916.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
这不就是把语法简化了一下,相应的builder.Services 对应Startup.cs 里面的ConfigureServices 方法,都是操作IServiceCollection,OK,Build之后我们得到了app ,这里对应的是Configure 方法。
![在这里插入图片描述](https://img-blog.csdnimg.cn/6925622b6cf0457abfdc2cb33e650ccd.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16) OK,了解了基本的项目架构,我们就可以很简单去扩展程序的中间件和管道。
开始使用
1. 安装所需要的Nuget包 ;
![在这里插入图片描述](https://img-blog.csdnimg.cn/0745bd864be4406c912e197b10f7ca76.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
2. 创建类库;
DemoDto、DemoEntity、DemoIRepository、DemoRepository、DemoISerive、DemoService类库,并添加Nuget包。
![在这里插入图片描述](https://img-blog.csdnimg.cn/efac84c05b5c4f959d186dc14341d7e0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16) ![在这里插入图片描述](https://img-blog.csdnimg.cn/cd418032d9c04c7cb5e77ce2be4a8a35.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
3.设计类库;
我们以Users表为基础 ![在这里插入图片描述](https://img-blog.csdnimg.cn/c94a8142c7ad4e81bcbe213a9d3a1197.png)
- Entity和Dto的配置
![在这里插入图片描述](https://img-blog.csdnimg.cn/1cdd1fe6baf1470b8b025fd03ef5c725.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
- IRepository与Repository的配置。
![在这里插入图片描述](https://img-blog.csdnimg.cn/4f489d4af2b94c3aaef3392f1d841b0c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
public interface IRepositoryUser : IEFRepository<UserContext, UserEntity>
{
Task<List<UserEntity>> GetAllList();
}
public class RepositoryUser : EFRepository<UserContext, UserEntity>, IRepositoryUser
{
public RepositoryUser(UserContext dbContext) : base(dbContext)
{
}
public async Task<List<UserEntity>> GetAllList()
{
return await DbContext.Set<UserEntity>().
FromSqlRaw(sql: "Select * from Users").ToListAsync();
}
}
- IService与Service层配置
需要新建一个IService的接口,不需要干任何东西 。为了IOC自动注入获取标记。 用心的小伙伴可能看到了,我们Service层用的DTO,Repository层用的是Entity ![在这里插入图片描述](https://img-blog.csdnimg.cn/acdc31d8cb4f4223a9e7f704fceedb08.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ium6YWS5YWl5ZaJ5b-D5L2c55eb,size_20,color_FFFFFF,t_70,g_se,x_16)
public interface IServiceUser : IService
{
Task<List<UserDto>> GetAllList();
}
public class ServiceUser : IServiceUser
{
private readonly IMapper _mapper;
private readonly IRepositoryUser _userRepository;
public ILogger<ServiceUser> _logger;
public ServiceUser(IMapper mapper,
IRepositoryUser userRepository,
ILogger<ServiceUser> logger)
{
_mapper = mapper;
_userRepository = userRepository;
_logger = logger;
}
public async Task<List<UserDto>> GetAllList()
{
var res = await _userRepository.GetAllList();
return _mapper.Map<List<UserDto>>(res);
}
}
- UserContext,这个我是写在了IRepository层。UserContext我们需要自动注入到DbContext。如下我们需要UserContext继承于DbContext重写OnModelCreating。这里就不做过多赘述了。
我们需要在Program.cs去注入,这个稍后我们在来看。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/d203e008de9b47d8a25727ecac207d72.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16)
public class UserContext : DbContext
{
public UserContext([NotNull] DbContextOptions<UserContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserEntity>().HasNoKey();
base.OnModelCreating(modelBuilder);
}
}
- 到了这一步,基本的关系我们是建立好了。接下来我们整合
项目整合
Program.cs类的配置
1.注入UserContext ,这里的GetConnectionString(“demo”),是我们在appsettings.json里面配置的连接字符串。
builder.Services.AddSqlServer<UserContext>(builder.Configuration.GetConnectionString("demo")!);
![在这里插入图片描述](https://img-blog.csdnimg.cn/df874bfbb00f4ae9b14b326556c53f4c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16)
2.注入AutoMapper ,DtoProfile是我们自定义的类。这里我放在了Service层。
builder.Services.AddAutoMapper(typeof(DtoProfile));
添加Dto=>Entity和Entity=>Dto的转换。后续添加功能需要添加映射关系,有些麻烦。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/f51d118cbdc743dfa31fa9fdfcd936b0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16) 3.Autofac——自动注入 我们使用模块注入,不用后续开发新模块再去添加(ps:AutoMapper)。
OK,在使用模块注入的时候,我们需要做一些准备工作。 1.在Web Api层添加一个autofac.json 文件,配置模块注入; type的第一个参数是文件的路径,第二个是命名空间 ![在这里插入图片描述](https://img-blog.csdnimg.cn/434c404f918f4287a1492111ee67ba7b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16)
using Autofac;
using Autofac.Configuration;
using Autofac.Extensions.DependencyInjection;
using DemoIRepository;
using DemoService;
var builder = WebApplication.CreateBuilder(args);
builder.Host.ConfigureAppConfiguration((context, config) =>
{
config.AddJsonFile("autofac.json", optional: true);
}).UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(con => {
con.RegisterModule(new ConfigurationModule(builder.Configuration));
});
builder.Services.AddAutoMapper(typeof(DtoProfile));
builder.Services.AddMvc();
builder.Services.AddSqlServer<UserContext>(builder.Configuration.GetConnectionString("demo")!);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
}
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
2.在DemoService类库下添加ServiceModule.cs类文件。继承于Autofac.Module。这里的IService是我们上面提到的,只是为了做标识。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/dd09df43139145ce9eb09e4e29cc5305.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16)
public class ServiceModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(this.ThisAssembly)
.Where(t => t.IsAssignableTo<IService>())
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
}
3.DemoRepository层也是如此 ![在这里插入图片描述](https://img-blog.csdnimg.cn/1c8280de4d4e489e9b0c155aee08691e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16)
public class RepositoryModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<UserContext>()
.As<DbContext>();
builder.RegisterAssemblyTypes(this.ThisAssembly)
.Where(t => t.IsClosedTypeOf(typeof(IRepository<>)))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
}
准备工作完毕,去Program.cs 配置。我们替换了自带的容器。
builder.Host.ConfigureAppConfiguration((context, config) =>
{
config.AddJsonFile("autofac.json", optional: true);
}).UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(con => {
con.RegisterModule(new ConfigurationModule(builder.Configuration));
});
添加UserController,跑起来。
![在这里插入图片描述](https://img-blog.csdnimg.cn/395d89dca8f843a7a33be1b2c30ea5cc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/cfda984dadbf4cea886119bcdaac8115.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16)
![在这里插入图片描述](https://img-blog.csdnimg.cn/7ab34802bba04524974b9a6d695a4683.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWljcm9zb2Z0IE12cA==,size_20,color_FFFFFF,t_70,g_se,x_16)
|