添加模块化功能+动态api

This commit is contained in:
陈淳
2023-01-11 15:05:31 +08:00
parent b2ac98d25e
commit 140f2970c4
43 changed files with 928 additions and 65 deletions

View File

@@ -1,7 +0,0 @@
namespace Yi.Framework.Application
{
public class Class1
{
}
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>Yi.Framework.Application</name>
</assembly>
<members>
</members>
</doc>

View File

@@ -0,0 +1,15 @@
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;
namespace Yi.Framework.Application
{
[DynamicWebApi]
public class TestService : IDynamicWebApi
{
public string GetShijie()
{
return "你好世界";
}
}
}

View File

@@ -1,9 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>./SwaggerDoc.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="SwaggerDoc.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using StartupModules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Application
{
public class YiFrameworkApplicationModule : IStartupModule
{
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
{
}
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
{
}
}
}

View File

@@ -1,7 +0,0 @@
namespace Yi.Framework.AspNetCore
{
public class Class1
{
}
}

View File

@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Builder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AspNetCore.Microsoft.AspNetCore.Builder
{
public static class CorsUseExtensions
{
public static void UseCorsService(this IApplicationBuilder app)
{
app.UseCors("CorsPolicy");
}
}
}

View File

@@ -0,0 +1,49 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AspNetCore.Microsoft.AspNetCore.Builder
{
public static class SwaggerUseExtensons
{
public static IApplicationBuilder UseSwaggerServer(this IApplicationBuilder app, params SwaggerModel[] swaggerModels)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
if (swaggerModels.Length == 0)
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Yi.Framework");
}
else
{
foreach (var k in swaggerModels)
{
c.SwaggerEndpoint(k.url, k.name);
}
}
});
return app;
}
}
public class SwaggerModel
{
public SwaggerModel(string url, string name)
{
this.url = url;
this.name = name;
}
public string url { get; set; }
public string name { get; set; }
}
}

View File

@@ -0,0 +1,64 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Attribute;
namespace Microsoft.Extensions.DependencyInjection
{
public static class AutoIocAddExtensions
{
public static IServiceCollection AddAutoIocServer(this IServiceCollection services, params string[] assemblyStr)
{
foreach (var a in assemblyStr)
{
RegIoc(services, Assembly.Load(a));
}
return services;
}
private static void RegIoc(IServiceCollection services, Assembly assembly)
{
foreach (var type in assembly.GetTypes())
{
var serviceAttribute = type.GetCustomAttribute<AppServiceAttribute>();
if (serviceAttribute is not null)
{
//情况1使用自定义[AppService(ServiceType = typeof(注册抽象或者接口))]手动去注册放type即可
var serviceType = serviceAttribute.ServiceType;
//情况2 自动去找接口,如果存在就是接口,如果不存在就是本身
if (serviceType == null)
{
//获取最靠近的接口
var firstInter = type.GetInterfaces().FirstOrDefault();
if (firstInter is null)
{
serviceType = type;
}
else
{
serviceType = firstInter;
}
}
switch (serviceAttribute.ServiceLifetime)
{
case LifeTime.Singleton:
services.AddSingleton(serviceType, type);
break;
case LifeTime.Scoped:
services.AddScoped(serviceType, type);
break;
case LifeTime.Transient:
services.AddTransient(serviceType, type);
break;
}
}
}
}
}
}

View File

@@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Extensions.DependencyInjection
{
public static class CorsAddExtensions
{
public static IServiceCollection AddCorsServer(this IServiceCollection services)
{
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyMethod()
.SetIsOriginAllowed(_ => true)
.AllowAnyHeader()
.AllowCredentials();
}));
return services;
}
}
}

View File

@@ -0,0 +1,74 @@
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Microsoft.Extensions.DependencyInjection
{
public static class SwaggerAddExtensions
{
public static IServiceCollection AddSwaggerServer<Program>(this IServiceCollection services, string title = "Yi意框架-API接口")
{
var apiInfo = new OpenApiInfo
{
Title = title,
Version = "v1",
Contact = new OpenApiContact { Name = "橙子", Email = "454313500@qq.com", Url = new Uri("https://ccnetcore.com") }
};
#region Swagger服务
services.AddSwaggerGen(c =>
{
c.DocInclusionPredicate((docName, description) => true);
c.SwaggerDoc("v1", apiInfo);
//添加注释服务
//为 Swagger JSON and UI设置xml文档注释路径
//获取应用程序所在目录(绝对路径不受工作目录影响建议采用此方法获取路径使用windwos&Linux
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
if (basePath is null)
{
throw new Exception("未找到swagger文件");
}
var apiXmlPath = Path.Combine(basePath, @"SwaggerDoc.xml");//控制器层注释
//var entityXmlPath = Path.Combine(basePath, @"SwaggerDoc.xml");//实体注释
//c.IncludeXmlComments(apiXmlPath, true);//true表示显示控制器注释
//c.IncludeXmlComments(apiXmlPath, true);
//这里路径应该动态获取,先暂时写死
//c.IncludeXmlComments("E:\\Yi\\src\\Yi.Framework\\Yi.Framework.Application\\SwaggerDoc.xml", true);
//添加控制器注释
//c.DocumentFilter<SwaggerDocTag>();
//添加header验证信息
//c.OperationFilter<SwaggerHeader>();
//var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, };
c.AddSecurityDefinition("JwtBearer", new OpenApiSecurityScheme()
{
Description = "直接输入Token即可",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "bearer"
});
var scheme = new OpenApiSecurityScheme()
{
Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "JwtBearer" }
};
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
[scheme] = new string[0]
});
});
#endregion
return services;
}
}
}

View File

@@ -6,4 +6,14 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,7 +0,0 @@
namespace Yi.Framework.Autofac
{
public class Class1
{
}
}

View File

@@ -0,0 +1,22 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Autofac.Extensions
{
public static class AutoFacExtensions
{
public static IHostBuilder UseAutoFacServerProviderFactory(this IHostBuilder hostBuilder)
{
hostBuilder.UseServiceProviderFactory(new AutofacServiceProviderFactory());
return hostBuilder;
}
}
}

View File

@@ -6,4 +6,13 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="AutofacModule\" />
</ItemGroup>
</Project>

View File

@@ -1,7 +0,0 @@
namespace Yi.Framework.Core.Sqlsugar
{
public class Class1
{
}
}

View File

@@ -0,0 +1,136 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Configuration;
using Yi.Framework.Core.Model;
using DbType = SqlSugar.DbType;
namespace Yi.Framework.Core.Sqlsugar.Extensions
{
public static class SqlsugarExtensions
{
public static void AddSqlsugarServer(this IServiceCollection services, Action<SqlSugarClient>? action = null)
{
DbType dbType;
var slavaConFig = new List<SlaveConnectionConfig>();
if (Appsettings.appBool("MutiDB_Enabled"))
{
var readCon = Appsettings.app<List<string>>("DbConn", "ReadUrl");
readCon.ForEach(s =>
{
//如果是动态saas分库这里的连接串都不能写死需要动态添加这里只配置共享库的连接
slavaConFig.Add(new SlaveConnectionConfig() { ConnectionString = s });
});
}
switch (Appsettings.app("DbSelect"))
{
case "Mysql": dbType = DbType.MySql; break;
case "Sqlite": dbType = DbType.Sqlite; break;
case "Sqlserver": dbType = DbType.SqlServer; break;
case "Oracle": dbType = DbType.Oracle; break;
default: throw new Exception("DbSelect配置写的TM是个什么东西");
}
SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
{
//准备添加分表分库
DbType = dbType,
ConnectionString = Appsettings.app("DbConn", "WriteUrl"),
IsAutoCloseConnection = true,
MoreSettings = new ConnMoreSettings()
{
DisableNvarchar = true
},
SlaveConnectionConfigs = slavaConFig,
//设置codefirst非空值判断
ConfigureExternalServices = new ConfigureExternalServices
{
EntityService = (c, p) =>
{
//// int? decimal?这种 isnullable=true
//if (c.PropertyType.IsGenericType &&
//c.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
//{
// p.IsNullable = true;
//}
//高版C#写法 支持string?和string
if (new NullabilityInfoContext()
.Create(c).WriteState is NullabilityState.Nullable)
{
p.IsNullable = true;
}
}
}
},
db =>
{
if (action is not null)
{
action(db);
}
db.Aop.DataExecuting = (oldValue, entityInfo) =>
{
//var httpcontext = ServiceLocator.Instance.GetService<IHttpContextAccessor>().HttpContext;
switch (entityInfo.OperationType)
{
case DataFilterType.InsertByObject:
if (entityInfo.PropertyName == "CreateUser")
{
//entityInfo.SetValue(new Guid(httpcontext.Request.Headers["Id"].ToString()));
}
if (entityInfo.PropertyName == "TenantId")
{
//entityInfo.SetValue(new Guid(httpcontext.Request.Headers["TenantId"].ToString()));
}
if (entityInfo.PropertyName == "CreateTime")
{
entityInfo.SetValue(DateTime.Now);
}
break;
case DataFilterType.UpdateByObject:
if (entityInfo.PropertyName == "ModifyTime")
{
entityInfo.SetValue(DateTime.Now);
}
if (entityInfo.PropertyName == "ModifyUser")
{
//entityInfo.SetValue(new Guid(httpcontext.Request.Headers["Id"].ToString()));
}
break;
}
};
db.Aop.OnLogExecuting = (s, p) =>
{
if (GobalLogModel.SqlLogEnable)
{
var _logger = ServiceLocatorModel.Instance?.GetRequiredService<ILogger<SqlSugarClient>>();
StringBuilder sb = new StringBuilder();
sb.Append("执行SQL:" + s.ToString());
foreach (var i in p)
{
sb.Append($"\r\n参数:{i.ParameterName},参数值:{i.Value}");
}
sb.Append($"\r\n 完整SQL{UtilMethods.GetSqlString(DbType.MySql, s, p)}");
_logger?.LogInformation(sb.ToString());
}
};
});
services.AddSingleton<ISqlSugarClient>(sqlSugar);//这边是SqlSugarScope用AddSingleton
}
}
}

View File

@@ -0,0 +1,23 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Attribute;
using Yi.Framework.Ddd.Repository;
namespace Yi.Framework.Core.Sqlsugar.Repository
{
[AppService]
public class SqlsugarRepository<T> : SimpleClient<T>, IRepository<T> where T : class, new()
{
public SqlsugarRepository(ISqlSugarClient context) : base(context)
{
}
protected ISugarQueryable<T> _DbQueryable { get { return base.Context.Queryable<T>(); } set { } }
protected ISqlSugarClient _Db { get { return base.Context; } set { } }
}
}

View File

@@ -6,4 +6,13 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SqlSugarCore" Version="5.1.3.43" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
<ProjectReference Include="..\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using StartupModules;
using Yi.Framework.Core.Sqlsugar.Extensions;
using Yi.Framework.Core.Sqlsugar.Repository;
using Yi.Framework.Ddd;
using Yi.Framework.Ddd.Repository;
namespace Yi.Framework.Core.Sqlsugar
{
public class YiFrameworkCoreSqlsugarModule : IStartupModule
{
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
{
}
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
{
services.AddTransient(typeof(IRepository<>), typeof(SqlsugarRepository<>));
services.AddSqlsugarServer();
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Attribute
{
/// 1、[AppService]:自动去找接口,如果存在就是接口,如果不存在就是本身
/// 2、[AppService(ServiceType = typeof(注册抽象或者接口或者本身))]手动去注册放type即可
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class AppServiceAttribute : System.Attribute
{
/// <summary>
/// 服务声明周期
/// 不给默认值的话注册的是作用域
/// </summary>
public LifeTime ServiceLifetime { get; set; } = LifeTime.Scoped;
/// <summary>
/// 指定服务类型
/// </summary>
public Type? ServiceType { get; set; }
}
public enum LifeTime
{
Transient, Scoped, Singleton
}
}

View File

@@ -0,0 +1,91 @@
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Configuration
{
public class Appsettings
{
static IConfiguration? Configuration { get; set; }
static string? contentPath { get; set; }
public Appsettings(string contentPath)
{
string Path = "appsettings.json";
//如果你把配置文件 是 根据环境变量来分开了,可以这样写
//Path = $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json";
Configuration = new ConfigurationBuilder()
.SetBasePath(contentPath)
.Add(new JsonConfigurationSource { Path = Path, Optional = false, ReloadOnChange = true })//这样的话可以直接读目录里的json文件而不是 bin 文件夹下的,所以不用修改复制属性
.Build();
}
public Appsettings(IConfiguration configuration)
{
Configuration = configuration;
}
/// <summary>
/// 封装要操作的字符
/// </summary>
/// <param name="sections">节点配置</param>
/// <returns></returns>
public static string? app(params string[] sections)
{
try
{
if (sections.Any())
{
return Configuration?[string.Join(":", sections)];
}
}
catch (Exception) { }
return "";
}
public static bool appBool(params string[] sections)
{
return Bool(app(sections));
}
public static bool Bool(object? thisValue)
{
bool reval = false;
if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return reval;
}
/// <summary>
/// 递归获取配置信息数组
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sections"></param>
/// <returns></returns>
public static T app<T>(params string[] sections)
{
T app = Activator.CreateInstance<T>();
// 引用 Microsoft.Extensions.Configuration.Binder 包
Configuration.Bind(string.Join(":", sections), app);
return app;
}
public static IConfiguration? appConfiguration(params string[] sections)
{
return Configuration?.GetSection(string.Join(":", sections));
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Model
{
public class GobalLogModel
{
public static bool SqlLogEnable { get; set; } = true;
public static bool LoginCodeEnable { get; set; } = true;
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Model
{
public static class ServiceLocatorModel
{
public static IServiceProvider? Instance { get; set; }
}
}

View File

@@ -1,13 +0,0 @@
using StartupModules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Module
{
public interface IYiModule: IStartupModule
{
}
}

View File

@@ -8,9 +8,11 @@
<ItemGroup>
<Folder Include="Extensions\" />
<Folder Include="Module\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.1" />
<PackageReference Include="StartupModules" Version="4.0.0" />
</ItemGroup>

View File

@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using StartupModules;
using System;
@@ -6,20 +7,27 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Module;
using Yi.Framework.Core.Configuration;
using Yi.Framework.Core.Model;
namespace Yi.Framework.Core
{
public class YiFrameworkCoreModule : IYiModule
public class YiFrameworkCoreModule : IStartupModule
{
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
{
throw new NotImplementedException();
//服务定位实例赋值
ServiceLocatorModel.Instance = app.ApplicationServices;
}
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
{
throw new NotImplementedException();
//添加全局配置类
services.AddSingleton(new Appsettings(context.Configuration));
//全局日志
GobalLogModel.SqlLogEnable = Appsettings.appBool("SqlLog_Enable");
GobalLogModel.LoginCodeEnable = Appsettings.appBool("LoginCode_Enable");
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Ddd.Repository
{
public interface IRepository<T>
{
Task<T> GetByIdAsync(dynamic id);
}
}

View File

@@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
</ItemGroup>
</Project>

View File

@@ -9,16 +9,14 @@ using System.Threading.Tasks;
namespace Yi.Framework.Ddd
{
public class YiFrameworkModule : IStartupModule
public class YiFrameworkDddModule:IStartupModule
{
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
{
throw new NotImplementedException();
}
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,28 +1,45 @@
using AspNetCore.Microsoft.AspNetCore.Builder;
using Panda.DynamicWebApi;
using Yi.Framework.Application;
using Yi.Framework.Core;
using Yi.Framework.Core.Extensions;
using Yi.Framework.Core.Sqlsugar;
using Yi.Framework.Core.Sqlsugar.Repository;
using Yi.Framework.Ddd;
using Yi.Framework.Ddd.Repository;
using Yi.Framework.Web;
var builder = WebApplication.CreateBuilder(args);
builder.UseYiModules();
// Add services to the container.
builder.UseYiModules(
typeof(YiFrameworkCoreModule).Assembly,
typeof(YiFrameworkDddModule).Assembly,
typeof(YiFrameworkCoreSqlsugarModule).Assembly
);
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddDynamicWebApi();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSwaggerServer<YiFrameworkApplicationModule>();
//builder.Services.AddAutoIocServer("Yi.Framework.Core.Sqlsugar");
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
app.Services.GetRequiredService<IRepository<TestEntity>>();
//if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
app.UseSwaggerServer();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseRouting();
app.MapControllers();
app.Run();

View File

@@ -0,0 +1,6 @@
namespace Yi.Framework.Web
{
public class TestEntity
{
}
}

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@@ -7,10 +7,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.Application\Yi.Framework.Application.csproj" />
<ProjectReference Include="..\Yi.Framework.AspNetCore\Yi.Framework.AspNetCore.csproj" />
<ProjectReference Include="..\Yi.Framework.Core.Sqlsugar\Yi.Framework.Core.Sqlsugar.csproj" />
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
</ItemGroup>

View File

@@ -1,9 +1,8 @@
using StartupModules;
using Yi.Framework.Core.Module;
namespace Yi.Framework.Web
{
public class YiFrameworkWebModule : IYiModule
public class YiFrameworkWebModule : IStartupModule
{
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
{

View File

@@ -5,5 +5,20 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
//数据库列表
"DbList": [ "Sqlite", "Mysql", "Sqlserver", "Oracle" ],
//数据库类型选择
"DbSelect": "Sqlite",
//数据库连接地址,支持读写分离
"DbConn": {
"WriteUrl": "DataSource=yi-sqlsugar-dev.db",
"ReadUrl": [
"DataSource=[xxxx]", //sqlite
"server=[xxxx];port=3306;database=[xxxx];user id=[xxxx];password=[xxxx]", //mysql
"Data Source=[xxxx];Initial Catalog=[xxxx];User ID=[xxxx];password=[xxxx]" //sqlserver
]
}
}

25
src/apiDemo/apiDemo.sln Normal file
View File

@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33103.184
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "apiDemo", "apiDemo\apiDemo.csproj", "{F283397C-2CD9-412B-A561-5BE263D8088A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F283397C-2CD9-412B-A561-5BE263D8088A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F283397C-2CD9-412B-A561-5BE263D8088A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F283397C-2CD9-412B-A561-5BE263D8088A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F283397C-2CD9-412B-A561-5BE263D8088A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {32430753-D4CB-4090-8ADF-E4C6FEC4824A}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,34 @@
using Panda.DynamicWebApi;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.DocInclusionPredicate((docName, description) => true);
options.IncludeXmlComments(@".\swagger.xml");
});
builder.Services.AddDynamicWebApi();
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();

View File

@@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:39272",
"sslPort": 44328
}
},
"profiles": {
"apiDemo": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7262;http://localhost:5013",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,13 @@
namespace apiDemo
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

View File

@@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Mvc;
using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;
namespace apiDemo
{
[DynamicWebApi]
[Route("[controller]")]
public class WeatherForecastController : IDynamicWebApi
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>.\swagger.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Panda.DynamicWebApi" Version="1.2.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>apiDemo</name>
</assembly>
<members>
</members>
</doc>