添加模块化功能+动态api
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
namespace Yi.Framework.Application
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
8
src/Yi.Framework/Yi.Framework.Application/SwaggerDoc.xml
Normal file
8
src/Yi.Framework/Yi.Framework.Application/SwaggerDoc.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>Yi.Framework.Application</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
||||
15
src/Yi.Framework/Yi.Framework.Application/TestService.cs
Normal file
15
src/Yi.Framework/Yi.Framework.Application/TestService.cs
Normal 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 "你好世界";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Yi.Framework.AspNetCore
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Yi.Framework.Autofac
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Yi.Framework.Core.Sqlsugar
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 { } }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/Yi.Framework/Yi.Framework.Core/Model/GobalLogModel.cs
Normal file
15
src/Yi.Framework/Yi.Framework.Core/Model/GobalLogModel.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,8 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
6
src/Yi.Framework/Yi.Framework.Web/TestEntity.cs
Normal file
6
src/Yi.Framework/Yi.Framework.Web/TestEntity.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Yi.Framework.Web
|
||||
{
|
||||
public class TestEntity
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
25
src/apiDemo/apiDemo.sln
Normal 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
|
||||
34
src/apiDemo/apiDemo/Program.cs
Normal file
34
src/apiDemo/apiDemo/Program.cs
Normal 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();
|
||||
31
src/apiDemo/apiDemo/Properties/launchSettings.json
Normal file
31
src/apiDemo/apiDemo/Properties/launchSettings.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13
src/apiDemo/apiDemo/WeatherForecast.cs
Normal file
13
src/apiDemo/apiDemo/WeatherForecast.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
35
src/apiDemo/apiDemo/WeatherForecastController.cs
Normal file
35
src/apiDemo/apiDemo/WeatherForecastController.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
src/apiDemo/apiDemo/apiDemo.csproj
Normal file
16
src/apiDemo/apiDemo/apiDemo.csproj
Normal 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>
|
||||
9
src/apiDemo/apiDemo/appsettings.json
Normal file
9
src/apiDemo/apiDemo/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
8
src/apiDemo/apiDemo/swagger.xml
Normal file
8
src/apiDemo/apiDemo/swagger.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>apiDemo</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
||||
Reference in New Issue
Block a user