This commit is contained in:
454313500@qq.com
2021-05-13 01:39:34 +08:00
parent 2e5b991db0
commit fe850bbc2c
53 changed files with 1318 additions and 404 deletions

View File

@@ -1,10 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="6.1.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -15,8 +18,34 @@
<ItemGroup>
<ProjectReference Include="..\CC.Yi.BLL\CC.Yi.BLL.csproj" />
<ProjectReference Include="..\CC.Yi.Common\CC.Yi.Common.csproj" />
<ProjectReference Include="..\CC.Yi.DAL\CC.Yi.DAL.csproj" />
<ProjectReference Include="..\CC.Yi.IBLL\CC.Yi.IBLL.csproj" />
<ProjectReference Include="..\CC.Yi.Model\CC.Yi.Model.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="nlog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<ItemGroup>
<Compile Update="T4Startup.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>T4Startup.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="T4Startup.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>T4Startup.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

View File

@@ -1,9 +1,22 @@
using CC.Yi.IBLL;
using CC.Yi.Common;
using CC.Yi.Common.Cache;
using CC.Yi.Common.Jwt;
using CC.Yi.IBLL;
using CC.Yi.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace CC.Yi.API.Controllers
@@ -12,19 +25,138 @@ namespace CC.Yi.API.Controllers
[Route("[controller]/[action]")]
public class StudentController : ControllerBase
{
private readonly ILogger<StudentController> _logger;
private readonly ILogger<StudentController> _logger;//处理日志相关文件
//private UserManager<result_user> _userManager;//处理用户相关逻辑:添加密码,修改密码,添加删除角色等等
//private SignInManager<result_user> _signInManager;//处理注册登录的相关逻辑
private IstudentBll _studentBll;
public StudentController(ILogger<StudentController> logger, IstudentBll studentBll)
{
_studentBll = studentBll;
_logger = logger;
_logger.LogInformation("现在你进入了StudentController控制器");
_studentBll = studentBll;
}
#region
//关于身份认证配置使用:
//在需要身份认证的控制器上打上 [Authorize] 特性标签
#endregion
//[HttpGet]
//public async Task<IActionResult> IdentityTest()
//{
// //用户登入
// var data = await _signInManager.PasswordSignInAsync("账号", "密码", false, false); //"是否记住密码","是否登入失败锁定用户"
// //用户登出
// await _signInManager.SignOutAsync();
// //创建用户
// var data2 = await _userManager.CreateAsync(new result_user { UserName="账户",Email="邮箱"},"密码");
// //获取用户
// var data3 = _userManager.Users;//这里可以使用Linq表达式Select
// return Ok();
//}
[HttpGet]
public Result GetReids()
{
var data = CacheHelper.CacheWriter.GetCache<string>("key01");
return Result.Success(data);
}
#region
//下面,权限验证
#endregion
//发送令牌
[HttpGet]
public Result Login(string role)
{
string userName = "admin";
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"),
new Claim(ClaimTypes.Name, userName),
new Claim(ClaimTypes.Role,role)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: JwtConst.Domain,
audience: JwtConst.Domain,
claims: claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
var tokenData = new JwtSecurityTokenHandler().WriteToken(token);
return Result.Success("欢迎你!管理员!").SetData(new { token = tokenData });
}
[HttpGet]
public IActionResult Test()
[Authorize(Policy = "myadmin")]//基于策略的验证
public Result MyAdmin()
{
var data = _studentBll.GetAllEntities().ToList();
return Content(Common.JsonFactory.JsonToString(data));
return Result.Success("欢迎你!管理员!");
}
[HttpGet]
[Authorize(Roles = "user")]//基于角色的验证
public Result MyUser()
{
return Result.Success("欢迎你!游客!");
}
#region
//下面,经典的 增删改查 即为简易--Yi意框架
//注意:请确保你的数据库中存在合理的数据
#endregion
[HttpGet]
public async Task<Result> GetTest()//查
{
_logger.LogInformation("调用查方法");
var data =await _studentBll.GetAllEntities().ToListAsync();
return Result.Success().SetData(data);
}
[HttpGet]
public Result AddTest()//增
{
_logger.LogInformation("调用增方法");
List<student> students = new List<student>() { new student { name = "学生a" }, new student { name = "学生d" } };
if (_studentBll.Add(students))
{
return Result.Success();
}
else
{
return Result.Error();
}
}
[HttpGet]
public Result RemoveTest()//删
{
_logger.LogInformation("调用删方法");
if (_studentBll.Delete(u => u.name == "学生a"))
{
return Result.Success();
}
else
{
return Result.Error();
}
}
[HttpGet]
public Result UpdateTest()//改
{
_logger.LogInformation("调用改方法");
if (_studentBll.Update(new student { id = 2, name = "学生a" }, "name"))
{
return Result.Success();
}
else
{
return Result.Error();
}
}
}
}

View File

@@ -0,0 +1,76 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
namespace CC.Yi.API.Extension
{
/// <summary>
/// Swagger文档扩展方法
/// </summary>
public static class SwaggerExtension
{
public static IServiceCollection AddSwaggerService(this IServiceCollection services)
{
var apiInfo = new OpenApiInfo
{
Title = "Yi意框架-API接口",
Version = "v1",
Contact = new OpenApiContact { Name = "橙子", Email = "454313500@qq.com", Url = new System.Uri("https://jiftcc.com") }
};
#region Swagger服务
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", apiInfo);
//添加注释服务
//为 Swagger JSON and UI设置xml文档注释路径
//获取应用程序所在目录(绝对路径不受工作目录影响建议采用此方法获取路径使用windwos&Linux
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
var apiXmlPath = Path.Combine(basePath, @"ApiDoc.xml");//控制器层注释
var entityXmlPath = Path.Combine(basePath, @"Model\ModelDoc.xml");//实体注释
//c.IncludeXmlComments(apiXmlPath, true);//true表示显示控制器注释
//c.IncludeXmlComments(entityXmlPath);
//添加控制器注释
//c.DocumentFilter<SwaggerDocTag>();
//添加header验证信息
//c.OperationFilter<SwaggerHeader>();
//var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, };
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Description = "文本框里输入从服务器获取的Token。格式为Bearer + 空格+token",//JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"
Name = "Authorization",////jwt默认的参数名称
In = ParameterLocation.Header,////jwt默认存放Authorization信息的位置(请求头中)
Type = SecuritySchemeType.ApiKey,
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{ new OpenApiSecurityScheme
{
Reference = new OpenApiReference()
{
Id = "Bearer",
Type = ReferenceType.SecurityScheme
}
}, Array.Empty<string>() }
});
});
#endregion
return services;
}
public static void UseSwaggerService(this IApplicationBuilder app)
{
//在 Startup.Configure 方法中,启用中间件为生成的 JSON 文档和 Swagger UI 提供服务:
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "JwtTest v1"));
}
}
}

View File

@@ -0,0 +1,21 @@
using CC.Yi.DAL;
using CC.Yi.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CC.Yi.API.Filter
{
public class DbContextFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
}
}

View File

@@ -2,33 +2,29 @@
using CC.Yi.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace CC.Yi.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20210319112041_yi1")]
partial class yi1
[Migration("20210413063257_y1")]
partial class y1
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.4")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
.HasAnnotation("ProductVersion", "5.0.5");
modelBuilder.Entity("CC.Yi.Model.student", b =>
{
b.Property<int>("id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
.HasColumnType("INTEGER");
b.Property<int>("name")
.HasColumnType("int");
b.Property<string>("name")
.HasColumnType("TEXT");
b.HasKey("id");

View File

@@ -2,7 +2,7 @@
namespace CC.Yi.API.Migrations
{
public partial class yi1 : Migration
public partial class y1 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
@@ -10,9 +10,9 @@ namespace CC.Yi.API.Migrations
name: "student",
columns: table => new
{
id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
name = table.Column<int>(type: "int", nullable: false)
id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
name = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{

View File

@@ -2,7 +2,6 @@
using CC.Yi.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace CC.Yi.API.Migrations
@@ -14,19 +13,16 @@ namespace CC.Yi.API.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("ProductVersion", "5.0.4")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
.HasAnnotation("ProductVersion", "5.0.5");
modelBuilder.Entity("CC.Yi.Model.student", b =>
{
b.Property<int>("id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
.HasColumnType("INTEGER");
b.Property<int>("name")
.HasColumnType("int");
b.Property<string>("name")
.HasColumnType("TEXT");
b.HasKey("id");

View File

@@ -1,7 +1,11 @@
using Autofac.Extensions.DependencyInjection;
using CC.Yi.DAL;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Web;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -13,14 +17,49 @@ namespace CC.Yi.API
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
try
{
logger.Debug("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Yi<59><69><EFBFBD><EFBFBD><EFBFBD>ܡ<EFBFBD><DCA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
var host = CreateHostBuilder(args).Build();
//var scope = host.Services.CreateScope();
//var services = scope.ServiceProvider;
//var context = services.GetRequiredService<Model.DataContext>();//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
//DbContentFactory.Initialize(context);//<2F><><EFBFBD>þ<EFBFBD>̬<EFBFBD><EFBFBD><E0B7BD>ע<EFBFBD><D7A2>
host.Run();
logger.Info("Yi<59><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>");
}
catch (Exception exception)
{
//NLog: catch setup errors
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
webBuilder.UseUrls("http://*:19000").UseStartup<Startup>();
}).UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureLogging(logging =>
{
// logging.ClearProviders(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><D0BF><EFBFBD>̨<EFBFBD><CCA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
}).UseNLog();//<2F><><EFBFBD><EFBFBD>nlog<6F><67>־<EFBFBD><D6BE><EFBFBD><EFBFBD>
}
}

View File

@@ -1,22 +1,30 @@
using Autofac;
using Autofac.Extras.DynamicProxy;
using CC.Yi.API.Extension;
using CC.Yi.BLL;
using CC.Yi.Common.Castle;
using CC.Yi.Common.Jwt;
using CC.Yi.DAL;
using CC.Yi.IBLL;
using CC.Yi.IDAL;
using CC.Yi.Model;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CC.Yi.API
@@ -33,20 +41,80 @@ namespace CC.Yi.API
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
services.AddAuthorization(options =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "CC.Yi.API", Version = "v1" });
//<2F><><EFBFBD>û<EFBFBD><C3BB>ڲ<EFBFBD><DAB2>Ե<EFBFBD><D4B5><EFBFBD>֤
options.AddPolicy("myadmin", policy =>
policy.RequireRole("admin"));
});
string connection = Configuration["ConnectionStringBySQL"];
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//<2F>Ƿ<EFBFBD><C7B7><EFBFBD>֤Issuer
ValidateAudience = true,//<2F>Ƿ<EFBFBD><C7B7><EFBFBD>֤Audience
ValidateLifetime = true,//<2F>Ƿ<EFBFBD><C7B7><EFBFBD>֤ʧЧʱ<D0A7><CAB1>
ClockSkew = TimeSpan.FromSeconds(30),
ValidateIssuerSigningKey = true,//<2F>Ƿ<EFBFBD><C7B7><EFBFBD>֤SecurityKey
ValidAudience = JwtConst.Domain,//Audience
ValidIssuer = JwtConst.Domain,//Issuer<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>ǩ<EFBFBD><C7A9>jwt<77><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey))//<2F>õ<EFBFBD>SecurityKey
};
});
services.AddControllers();
services.AddSwaggerService();
services.AddSession();
//<2F><><EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD>
Action<MvcOptions> filters = new Action<MvcOptions>(r => {
//r.Filters.Add(typeof(DbContextFilter));
});
services.AddMvc(filters);
string connection1 = Configuration["ConnectionStringBySQL"];
string connection2 = Configuration["ConnectionStringByMySQL"];
string connection3 = Configuration["ConnectionStringBySQLite"];
services.AddDbContext<DataContext>(options =>
{
options.UseSqlServer(connection, b => b.MigrationsAssembly("CC.Yi.API"));//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD>
options.UseSqlite(connection3, b => b.MigrationsAssembly("CC.Yi.API"));//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD>
});
services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>));
services.AddScoped(typeof(IstudentBll), typeof(studentBll));
//<2F><><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>Autofac
//services.AddScoped(typeof(IBaseDal<>), typeof(BaseDal<>));
//services.AddScoped(typeof(IstudentBll), typeof(studentBll));
//<2F><><EFBFBD><EFBFBD>Identity<74><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
//services.AddIdentity<result_user, IdentityRole>(options =>
// {
// options.Password.RequiredLength = 6;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD><CCB3><EFBFBD>
// options.Password.RequireDigit = false;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// options.Password.RequireLowercase = false;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сд<D0A1><D0B4>ĸ
// options.Password.RequireNonAlphanumeric = false;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
// options.Password.RequireUppercase = false;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ĸ
// //options.User.RequireUniqueEmail = false;//ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2>ظ<EFBFBD>
// //options.User.AllowedUserNameCharacters="abcd"//<2F><><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
//}).AddEntityFrameworkStores<DataContext>().AddDefaultTokenProviders();
services.AddCors(options => options.AddPolicy("CorsPolicy",//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
builder =>
{
builder.AllowAnyMethod()
.SetIsOriginAllowed(_ => true)
.AllowAnyHeader()
.AllowCredentials();
}));
}
//<2F><>ʼ<EFBFBD><CABC>ʹ<EFBFBD>ú<EFBFBD><C3BA><EFBFBD>
private void InitData(IServiceProvider serviceProvider)
{
//var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope();
//var context = serviceScope.ServiceProvider.GetService<DataContext>();
//DbContentFactory.Initialize(context);//<2F><><EFBFBD>þ<EFBFBD>̬<EFBFBD><EFBFBD><E0B7BD>ע<EFBFBD><D7A2>
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -55,20 +123,22 @@ namespace CC.Yi.API
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "CC.Yi.API v1"));
app.UseSwaggerService();
}
app.UseCors("CorsPolicy");
app.UseHttpsRedirection();
app.UseSession();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
InitData(app.ApplicationServices);
}
}
}

23
CC.Yi.API/T4Startup.cs Normal file
View File

@@ -0,0 +1,23 @@
using Autofac;
using Autofac.Extras.DynamicProxy;
using CC.Yi.BLL;
using CC.Yi.Common.Castle;
using CC.Yi.DAL;
using CC.Yi.IBLL;
using CC.Yi.IDAL;
using System;
namespace CC.Yi.API
{
public partial class Startup
{
//动态 面向AOP思想的依赖注入 Autofac
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType(typeof(CustomAutofacAop));
builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>));
builder.RegisterType<studentBll>().As<IstudentBll>().EnableInterfaceInterceptors();//表示注入前后要执行CastleAOP
}
}
}

View File

@@ -13,24 +13,28 @@
sr.Close();
string[] ModelData= txt.Split(',');
#>
using Autofac;
using Autofac.Extras.DynamicProxy;
using CC.Yi.BLL;
using CC.Yi.Common.Castle;
using CC.Yi.DAL;
using CC.Yi.IBLL;
using CC.Yi.IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CC.Yi.DALFactory
namespace CC.Yi.API
{
public partial class DbSession : IDbSession
public partial class Startup
{
<# foreach(string k in ModelData){
#>
public I<#=k #>Dal <#=k #>Dal
//动态 面向AOP思想的依赖注入 Autofac
public void ConfigureContainer(ContainerBuilder builder)
{
get { return StaticDalFactory.Get<#=k #>Dal(); }
}
builder.RegisterType(typeof(CustomAutofacAop));
builder.RegisterGeneric(typeof(BaseDal<>)).As(typeof(IBaseDal<>));
<# foreach(string k in ModelData){#>
builder.RegisterType<<#=k #>Bll>().As<I<#=k #>Bll>().EnableInterfaceInterceptors();//表示注入前后要执行CastleAOP
<# } #>
}
}
}

BIN
CC.Yi.API/YIDB.db Normal file

Binary file not shown.

View File

@@ -7,6 +7,8 @@
}
},
"AllowedHosts": "*",
"ConnectionStringBySQL": "server=.;Database=cctest;UId=sa;PWD=Qz52013142020.",
"ConnectionStringByMySQL": "Data Source=49.235.212.122;Database=GraduationProject;User ID=root;Password=Qz52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;"
"ConnectionStringBySQL": "server=.;Database=YIDB;UId=sa;PWD=52013142020.",
"ConnectionStringByMySQL": "Data Source=.;Database=YIDB;User ID=root;Password=52013142020.;pooling=true;port=3306;sslmode=none;CharSet=utf8;",
"ConnectionStringBySQLite": "Filename=YIDB.db"
}

35
CC.Yi.API/nlog.config Normal file
View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwExceptions="false"
internalLogLevel="Warn"
internalLogFile="Logs\internal-nlog.txt">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<targets>
<!-- 写入文件配置 -->
<!-- write logs to file -->
<target xsi:type="File" name="allfile" fileName="Logs\nlog-all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring} ${newline}" />
<!-- another file log, only own logs. Uses some ASP.NET core renderers -->
<target xsi:type="File" name="ownFile-web" fileName="Logs\nlog-own-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action} ${newline}" />
</targets>
<rules>
<!--All logs, including from Microsoft-->
<!--minlevel 改为Trace 跟踪全部 Error 只捕获异常-->
<logger name="*" minlevel="Trace" writeTo="allfile" />
<!--Skip non-critical Microsoft logs and so log only own logs-->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<!-- BlackHole without writeTo -->
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>

View File

@@ -1,6 +1,7 @@
using CC.Yi.DALFactory;
using CC.Yi.IBLL;
using CC.Yi.IBLL;
using CC.Yi.IDAL;
using CC.Yi.Model;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -11,10 +12,13 @@ namespace CC.Yi.BLL
public class BaseBll<T> : IBaseBll<T> where T : class, new()
{
public IBaseDal<T> CurrentDal;
public BaseBll(IBaseDal<T> cd)
public DbContext DbSession;
public BaseBll(IBaseDal<T> cd, DataContext _Db)
{
CurrentDal = cd;
DbSession = _Db;
}
public IQueryable<T> GetAllEntities()
{
return CurrentDal.GetAllEntities();
@@ -49,37 +53,53 @@ namespace CC.Yi.BLL
return entity;
}
public bool Add(IEnumerable<T> entities)
{
CurrentDal.AddRange(entities);
return DbSession.SaveChanges() > 0;
}
public bool Update(T entity)
{
CurrentDal.Update(entity);
return DbSession.SaveChanges() > 0;
}
public bool Update(T entity, params string[] propertyNames)
{
CurrentDal.Update(entity,propertyNames);
return DbSession.SaveChanges() > 0;
}
public bool Delete(T entity)
{
CurrentDal.Delete(entity);
return DbSession.SaveChanges() > 0;
}
public IDbSession DbSession
{
get
{
return DbSessionFactory.GetCurrentDbSession();
}
}
public bool Delete(int id)
{
CurrentDal.Detete(id);
return DbSession.SaveChanges() > 0;
}
public int DeleteList(List<int> ids)
public bool Delete(IEnumerable<int> ids)
{
foreach (var id in ids)
{
CurrentDal.Detete(id);
}
return DbSession.SaveChanges();//这里把SaveChanges方法提到了循环体外自然就与数据库交互一次
return DbSession.SaveChanges()>0;
}
public bool Delete(Expression<Func<T, bool>> where)
{
IQueryable<T> entities = CurrentDal.GetEntities(where);
if (entities != null)
{
CurrentDal.DeteteRange(entities);
return DbSession.SaveChanges()>0;
}
return false;
}
}

View File

@@ -5,7 +5,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\CC.Yi.DALFactory\CC.Yi.DALFactory.csproj" />
<ProjectReference Include="..\CC.Yi.IBLL\CC.Yi.IBLL.csproj" />
<ProjectReference Include="..\CC.Yi.IDAL\CC.Yi.IDAL.csproj" />
</ItemGroup>

View File

@@ -6,14 +6,16 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace CC.Yi.BLL
{
public partial class studentBll : BaseBll<student>, IstudentBll
{
public studentBll(IBaseDal<student> cd):base(cd)
public studentBll(IBaseDal<student> cd,DataContext _Db):base(cd,_Db)
{
CurrentDal = cd;
DbSession = _Db;
}
}
}

View File

@@ -21,6 +21,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace CC.Yi.BLL
{
@@ -28,9 +29,10 @@ namespace CC.Yi.BLL
#>
public partial class <#=k #>Bll : BaseBll<<#=k #>>, I<#=k #>Bll
{
public <#=k #>Bll(IBaseDal<<#=k #>> cd):base(cd)
public <#=k #>Bll(IBaseDal<<#=k #>> cd,DataContext _Db):base(cd,_Db)
{
CurrentDal = cd;
DbSession = _Db;
}
}
<# } #>

View File

@@ -1,11 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="6.0.0" />
<PackageReference Include="Castle.Core" Version="4.4.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.11.0" />
<PackageReference Include="ServiceStack.Redis" Version="5.10.4" />
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,51 @@
using Autofac;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Text;
namespace CC.Yi.Common.Cache
{
public class CacheHelper
{
public static ICacheWriter CacheWriter { get; set; }
static CacheHelper()
{
CacheHelper.CacheWriter = new RedisCache();
}
public bool AddCache<T>(string key, T value, DateTime expDate)
{
return CacheWriter.AddCache<T>(key,value,expDate);
}
public bool AddCache<T>(string key, T value)
{
return CacheWriter.AddCache<T>(key, value);
}
public bool RemoveCache(string key)
{
return CacheWriter.RemoveCache(key);
}
public T GetCache<T>(string key)
{
return CacheWriter.GetCache<T>(key);
}
public bool SetCache<T>(string key, T value, DateTime expDate)
{
return CacheWriter.SetCache<T>(key,value,expDate);
}
public bool SetCache<T>(string key, T value)
{
return CacheWriter.SetCache<T>(key, value);
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CC.Yi.Common.Cache
{
public interface ICacheWriter
{
bool AddCache<T>(string key, T value, DateTime expDate);
bool AddCache<T>(string key, T value);
bool RemoveCache(string key);
T GetCache<T>(string key);
bool SetCache<T>(string key, T value, DateTime expDate);
bool SetCache<T>(string key, T value);
}
}

View File

@@ -0,0 +1,46 @@
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Text;
namespace CC.Yi.Common.Cache
{
public class RedisCache : ICacheWriter
{
private RedisClient client;
public RedisCache()
{
client = new RedisClient("127.0.0.1", 6379, "52013142020.");
}
public bool AddCache<T>(string key, T value, DateTime expDate)
{
return client.Add<T>(key, value, expDate);
}
public bool AddCache<T>(string key, T value)
{
return client.Add<T>(key, value);
}
public bool RemoveCache(string key)
{
return client.Remove(key);
}
public T GetCache<T>(string key)
{
return client.Get<T>(key);
}
public bool SetCache<T>(string key,T value, DateTime expDate)
{
return client.Set<T>(key, value, expDate);
}
public bool SetCache<T>(string key, T value)
{
return client.Set<T>(key, value);
}
}
}

View File

@@ -0,0 +1,23 @@
using Castle.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Text;
namespace CC.Yi.Common.Castle
{
public class CustomAutofacAop : IInterceptor
{
public void Intercept(IInvocation invocation)
{
{
//这里写执行方法前
}
invocation.Proceed();//执行具体的实例
{
//这里写执行方法后
}
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace CC.Yi.Common
{
public static class HttpHelper
{
public static string HttpGet(string Url, string postDataStr="")
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
return retString;
}
public static bool HttpIOGet(string Url, string file, string postDataStr="")
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
FileStream writer = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
byte[] buffer = new byte[1024];
int c;
while ((c = myResponseStream.Read(buffer, 0, buffer.Length)) > 0)
{
writer.Write(buffer, 0, c);
}
writer.Close();
myResponseStream.Close();
return true;
}
public static string HttpPost(string Url, string postDataStr="")
{
CookieContainer cookie = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr);
request.CookieContainer = cookie;
Stream myRequestStream = request.GetRequestStream();
StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312"));
myStreamWriter.Write(postDataStr);
myStreamWriter.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Cookies = cookie.GetCookies(response.ResponseUri);
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
return retString;
}
}
}

View File

@@ -1,12 +0,0 @@
using System;
namespace CC.Yi.Common
{
public static class JsonFactory
{
public static string JsonToString(object q)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(q);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
namespace CC.Yi.Common
{
public static class JsonHelper
{
public static string JsonToString(object data = null, int code = 200, bool flag = true, string message = "成功")
{
return Newtonsoft.Json.JsonConvert.SerializeObject(new { code = code, flag = flag, message = message, data = data });
}
public static string JsonToString2(object data = null, int code = 200, bool flag = true, string message = "成功", int count = 0)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(new { code = code, flag = flag, message = message, count = count, data = data });
}
public static string ToString(object data)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(data);
}
public static T ToJson<T>(string data)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(data);
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CC.Yi.Common.Jwt
{
public class JwtConst
{
public const string SecurityKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB";
public const string Domain = "http://localhost:5000";
}
}

40
CC.Yi.Common/Result.cs Normal file
View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace CC.Yi.Common
{
/// <summary>
/// 结果数据
/// </summary>
public class Result
{
public bool status { get; set; }
public int code { get; set; }
public string msg { get; set; }
public object data { get; set; }
public static Result Instance(bool status, string msg)
{
return new Result() { status = status,code=500, msg = msg };
}
public static Result Error(string msg="fail")
{
return new Result() { status = false, code = 500, msg = msg };
}
public static Result Success(string msg= "succeed")
{
return new Result() { status = true, code = 200, msg = msg };
}
public Result SetData(object obj)
{
this.data = obj;
return this;
}
public Result SetCode(int Code)
{
this.code = Code;
return this;
}
}
}

167
CC.Yi.Common/imageHelper.cs Normal file
View File

@@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using System.IO.Compression;
using System.Drawing;
namespace CC.Yi.Common
{
public class SimilarPhoto
{
Image SourceImg;
public SimilarPhoto(string filePath)
{
SourceImg = Image.FromFile(filePath);
}
public SimilarPhoto(Stream stream)
{
SourceImg = Image.FromStream(stream);
}
public String GetHash()
{
Image image = ReduceSize();
Byte[] grayValues = ReduceColor(image);
Byte average = CalcAverage(grayValues);
String reslut = ComputeBits(grayValues, average);
return reslut;
}
// Step 1 : Reduce size to 8*8
private Image ReduceSize(int width = 8, int height = 8)
{
Image image = SourceImg.GetThumbnailImage(width, height, () => { return false; }, IntPtr.Zero);
return image;
}
// Step 2 : Reduce Color
private Byte[] ReduceColor(Image image)
{
Bitmap bitMap = new Bitmap(image);
Byte[] grayValues = new Byte[image.Width * image.Height];
for (int x = 0; x < image.Width; x++)
for (int y = 0; y < image.Height; y++)
{
Color color = bitMap.GetPixel(x, y);
byte grayValue = (byte)((color.R * 30 + color.G * 59 + color.B * 11) / 100);
grayValues[x * image.Width + y] = grayValue;
}
return grayValues;
}
// Step 3 : Average the colors
private Byte CalcAverage(byte[] values)
{
int sum = 0;
for (int i = 0; i < values.Length; i++)
sum += (int)values[i];
return Convert.ToByte(sum / values.Length);
}
// Step 4 : Compute the bits
private String ComputeBits(byte[] values, byte averageValue)
{
char[] result = new char[values.Length];
for (int i = 0; i < values.Length; i++)
{
if (values[i] < averageValue)
result[i] = '0';
else
result[i] = '1';
}
SourceImg.Dispose();
return new String(result);
}
// Compare hash
public static Int32 CalcSimilarDegree(string a, string b)
{
if (a.Length != b.Length)
throw new ArgumentException();
int count = 0;
for (int i = 0; i < a.Length; i++)
{
if (a[i] != b[i])
count++;
}
return count;
}
}
public static class imageHelper
{
public static int Compare(string filePath1, string filePath2)
{
SimilarPhoto photo1 = new SimilarPhoto(filePath1);
SimilarPhoto photo2 = new SimilarPhoto(filePath2);
return SimilarPhoto.CalcSimilarDegree(photo1.GetHash(), photo2.GetHash());
}
public static bool ByStringToSave(string name, string iss)
{
iss = iss.Replace("data:image/png;base64,", "").Replace("data:image/jgp;base64,", "")
.Replace("data:image/jpg;base64,", "").Replace("data:image/jpeg;base64,", "");
byte[] arr = Convert.FromBase64String(iss);
MemoryStream ms = new MemoryStream(arr);
Bitmap bmp = new Bitmap(ms);
string StudentWorkImages = "StudentWorkImages";
if (Directory.Exists(@"./wwwroot/" + StudentWorkImages) == false)//如果不存在就创建file文件夹
{
Directory.CreateDirectory(@"./wwwroot/" + StudentWorkImages);
}
bmp.Save(@"./wwwroot/" + StudentWorkImages + "/" + name + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Close();
return true;
}
public static bool CreateZip()
{
string file_path = @"./wwwroot/StudentWorkImages.zip";
string file_path2 = @"./wwwroot/StudentWorkImages/";
if (File.Exists(file_path))
{
File.Delete(file_path);
}
ZipFile.CreateFromDirectory(file_path2, file_path);
return true;
}
public static bool DeleteAll()
{
string file_path = @"./wwwroot/StudentWorkImages/";
if (Directory.Exists(file_path))
{
DelectDir(file_path);
return true;
}
else
return false;
}
public static bool DeleteByString(string name)
{
File.Delete(@"./wwwroot/StudentWorkImages/" + name + ".jpg");
return true;
}
public static void DelectDir(string srcPath)
{
try
{
DirectoryInfo dir = new DirectoryInfo(srcPath);
FileSystemInfo[] fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo) //判断是否文件夹
{
DirectoryInfo subdir = new DirectoryInfo(i.FullName);
subdir.Delete(true); //删除子目录和文件
}
else
{
File.Delete(i.FullName); //删除指定文件
}
}
}
catch (Exception e)
{
Console.Write(e.ToString());
}
}
}
}

View File

@@ -1,7 +1,9 @@
using CC.Yi.IDAL;
using CC.Yi.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
@@ -9,7 +11,7 @@ namespace CC.Yi.DAL
{
public class BaseDal<T> : IBaseDal<T> where T : class, new()
{
public DataContext Db;
public DbContext Db;
public BaseDal(DataContext _Db)
{
Db = _Db;
@@ -65,6 +67,11 @@ namespace CC.Yi.DAL
//Db.SaveChanges();
return entity;
}
public bool AddRange(IEnumerable<T> entities)
{
Db.Set<T>().AddRange(entities);
return true;
}
public bool Update(T entity)
{
@@ -73,7 +80,16 @@ namespace CC.Yi.DAL
//return Db.SaveChanges() > 0;
return true;
}
public bool Update(T entity, params string[] propertyNames)
{
EntityEntry entry = Db.Entry<T>(entity);
entry.State = EntityState.Unchanged;
foreach (var item in propertyNames)
{
entry.Property(item).IsModified = true;
}
return true;
}
public bool Delete(T entity)
{
@@ -87,6 +103,12 @@ namespace CC.Yi.DAL
Db.Set<T>().Remove(entity);//由于这里先Find找到了实体所以这里可以用Remove标记该实体要移除删除。如果不是先Find到实体就需要用System.Data.Entity.EntityState.Deleted
return true;
}
public bool DeteteRange(IEnumerable<T> entity)
{
Db.Set<T>().RemoveRange(entity);
return true;
}
}
}

View File

@@ -1,50 +0,0 @@
using CC.Yi.Model;
using Microsoft.EntityFrameworkCore;
using System.Collections.Concurrent;
using System.Threading;
namespace CC.Yi.DAL
{
public class DbContentFactory
{
private static DataContext Webcontext;
public DbContentFactory(DataContext webContext)
{
Webcontext = webContext;
}
//public static void Initialize(DataContext webContext)
//{
// Webcontext = webContext;
//}
public static DataContext GetCurrentDbContent()
{
////return new DataModelContainer();
////一次请求共用一个上下文实例
////每一次http请求都会开启一个新的线程保证在一个线程中,DbContext是唯一的
////CallContext是线程内部唯一的数据槽一块内存空间/容器),相当于一个键值对数据容器通过key获取value了,需要引入System.Runtime.Remoting.Messaging;命名空间
//DbContext db = CallContext.GetData("DbContext") as DbContext;
////从 CallContext 中检索具有指定key“DbContext”的对象并强转为DbContext
//if (db == null)//线程在数据槽里面没有此上下文
//{
// db = Webcontext;
// CallContext.SetData("DbContext", db);//放到数据槽中去,DbContext是keydb是value
//}
//return db;
return Webcontext;
}
//private static class CallContext
//{
// static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();
// public static void SetData(string name, object data) =>
// state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;
// public static object GetData(string name) =>
// state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;
//}
}
}

View File

@@ -3,13 +3,15 @@ using CC.Yi.Model;
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
namespace CC.Yi.DAL
{
public partial class studentDal : BaseDal<student>, IstudentDal
{
public studentDal(DataContext _Db) : base(_Db)
public studentDal(DataContext _Db):base(_Db)
{
Db = _Db;
}
}
}

View File

@@ -18,6 +18,7 @@ using CC.Yi.Model;
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
namespace CC.Yi.DAL
{
@@ -25,8 +26,9 @@ namespace CC.Yi.DAL
#>
public partial class <#=k #>Dal : BaseDal<<#=k #>>, I<#=k #>Dal
{
public <#=k #>Dal(DataContext _Db) : base(_Db)
public <#=k #>Dal(DataContext _Db):base(_Db)
{
Db = _Db;
}
}
<# } #>

View File

@@ -1,40 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\CC.Yi.DAL\CC.Yi.DAL.csproj" />
<ProjectReference Include="..\CC.Yi.IDAL\CC.Yi.IDAL.csproj" />
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<ItemGroup>
<Compile Update="T4DbSession.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>T4DbSession.tt</DependentUpon>
</Compile>
<Compile Update="T4StaticDalFactory.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>T4StaticDalFactory.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="T4DbSession.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>T4DbSession.cs</LastGenOutput>
</None>
<None Update="T4StaticDalFactory.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>T4StaticDalFactory.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

View File

@@ -1,21 +0,0 @@
using CC.Yi.DAL;
using CC.Yi.IDAL;
using CC.Yi.Model;
using Microsoft.EntityFrameworkCore;
using System;
namespace CC.Yi.DALFactory
{
public partial class DbSession : IDbSession
{
public int SaveChanges()
{
return DbContentFactory.GetCurrentDbContent().SaveChanges();
}
public DataContext GetDbContent()
{
return DbContentFactory.GetCurrentDbContent();
}
}
}

View File

@@ -1,35 +0,0 @@
using CC.Yi.IDAL;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace CC.Yi.DALFactory
{
public class DbSessionFactory
{
public static IDbSession GetCurrentDbSession()
{
IDbSession db = CallContext.GetData("DbSession") as IDbSession;
if (db == null)
{
db = new DbSession();
CallContext.SetData("DbSession", db);
}
return db;
}
private static class CallContext
{
static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();
public static void SetData(string name, object data) =>
state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;
public static object GetData(string name) =>
state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;
}
}
}

View File

@@ -1,24 +0,0 @@
using CC.Yi.DAL;
using CC.Yi.IDAL;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace CC.Yi.DALFactory
{
public partial class StaticDalFactory
{
private static class CallContext
{
static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();
public static void SetData(string name, object data) =>
state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;
public static object GetData(string name) =>
state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;
}
}
}

View File

@@ -1,18 +0,0 @@
using CC.Yi.DAL;
using CC.Yi.IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CC.Yi.DALFactory
{
public partial class DbSession : IDbSession
{
public IstudentDal studentDal
{
get { return StaticDalFactory.GetstudentDal(); }
}
}
}

View File

@@ -1,25 +0,0 @@
using CC.Yi.DAL;
using CC.Yi.IDAL;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace CC.Yi.DALFactory
{
public partial class StaticDalFactory
{
public static IstudentDal GetstudentDal()
{
IstudentDal Data = CallContext.GetData("studentDal") as IstudentDal;
if (Data == null)
{
Data = new studentDal(DbSessionFactory.GetCurrentDbSession().GetDbContent());
CallContext.SetData("studentDal", Data);
}
return Data;
}
}
}

View File

@@ -1,43 +0,0 @@
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".cs" #>
<#
string solutionsPath = Host.ResolveAssemblyReference("$(SolutionDir)");//获取解决方案路径
string txt;
StreamReader sr = new StreamReader(solutionsPath+@"\T4Model\T4Model.txt");
txt=sr.ReadToEnd();
sr.Close();
string[] ModelData= txt.Split(',');
#>
using CC.Yi.DAL;
using CC.Yi.IDAL;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace CC.Yi.DALFactory
{
public partial class StaticDalFactory
{
<# foreach(string k in ModelData){
#>
public static I<#=k #>Dal Get<#=k #>Dal()
{
I<#=k #>Dal Data = CallContext.GetData("<#=k #>Dal") as I<#=k #>Dal;
if (Data == null)
{
Data = new <#=k #>Dal(DbSessionFactory.GetCurrentDbSession().GetDbContent());
CallContext.SetData("<#=k #>Dal", Data);
}
return Data;
}
<# } #>
}
}

View File

@@ -6,6 +6,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\CC.Yi.Common\CC.Yi.Common.csproj" />
<ProjectReference Include="..\CC.Yi.Model\CC.Yi.Model.csproj" />
</ItemGroup>

View File

@@ -1,4 +1,5 @@
using System;
using Autofac.Extras.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
@@ -11,6 +12,7 @@ namespace CC.Yi.IBLL
//得到全部实体
#endregion
IQueryable<T> GetAllEntities();
#region
//通过表达式得到实体
#endregion
@@ -36,11 +38,21 @@ namespace CC.Yi.IBLL
#endregion
T Add(T entity);
#region
//添加多个实体
#endregion
bool Add(IEnumerable<T> entities);
#region
//更新实体
#endregion
bool Update(T entity);
#region
//更新实体部分属性
#endregion
bool Update(T entity, params string[] propertyNames);
#region
//删除实体
#endregion
@@ -54,6 +66,11 @@ namespace CC.Yi.IBLL
#region
//通过id列表删除多个实体
#endregion
int DeleteList(List<int> ids);
bool Delete(IEnumerable<int> ids);
#region
//通过表达式删除实体
#endregion
bool Delete(Expression<Func<T, bool>> where);
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
@@ -36,11 +37,20 @@ namespace CC.Yi.IDAL
#endregion
T Add(T entity);
#region
//添加多个实体
#endregion
bool AddRange(IEnumerable<T> entities);
#region
//更新单个实体
#endregion
bool Update(T entity);
#region
//更新单个实体部分属性
#endregion
bool Update(T entity, params string[] propertyNames);
#region
//删除单个实体
#endregion
@@ -50,5 +60,10 @@ namespace CC.Yi.IDAL
//通过id删除实体
#endregion
bool Detete(int id);
#region
//删除多个实体
#endregion
bool DeteteRange(IEnumerable<T> entity);
}
}

View File

@@ -1,18 +0,0 @@
using CC.Yi.Model;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CC.Yi.IDAL
{
public partial interface IDbSession
{
DataContext GetDbContent();
int SaveChanges();
}
}

View File

@@ -5,28 +5,14 @@
</PropertyGroup>
<ItemGroup>
<None Include="T4DataContext.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>T4DataContext.tt</DependentUpon>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<None Update="T4DataContext.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>T4DataContext.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
@@ -39,4 +25,11 @@
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="T4DataContext.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>T4DataContext.cs</LastGenOutput>
</None>
</ItemGroup>
</Project>

View File

@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CC.Yi.Model
{
public partial class DataContext :DbContext

View File

@@ -17,7 +17,6 @@ using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
namespace CC.Yi.Model
{
public partial class DataContext :DbContext

View File

@@ -11,6 +11,6 @@ namespace CC.Yi.Model
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
public int name { get; set; }
public string name { get; set; }
}
}

View File

@@ -1,12 +0,0 @@
using System;
namespace CC.Yi.ViewModel
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

View File

@@ -29,8 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CC.Yi.ViewModel", "CC.Yi.Vi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CC.Yi.Common", "CC.Yi.Common\CC.Yi.Common.csproj", "{9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CC.Yi.DALFactory", "CC.Yi.DALFactory\CC.Yi.DALFactory.csproj", "{ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -69,10 +67,6 @@ Global
{9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC}.Release|Any CPU.Build.0 = Release|Any CPU
{ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -86,7 +80,6 @@ Global
{8827547B-E04B-4430-A0DF-E87FCA40E3AB} = {38B8D898-4BBF-4DDB-8E29-6D6CEB7808C9}
{32F323F1-E2FA-4186-AC33-263465012D15} = {38B8D898-4BBF-4DDB-8E29-6D6CEB7808C9}
{9D6E5DD7-FA02-4532-8BAC-406FB80AFEAC} = {123D1D39-849C-4220-A973-EB9760421CB3}
{ACB6D3EE-FADE-4F07-9D12-C9E3A5F72335} = {9D0D4A54-057E-46C3-BBFE-CA01F7ECEDAE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {22DD3529-6AD4-413A-B7B3-D8335E6F47C9}

201
LICENSE Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

55
README.md Normal file
View File

@@ -0,0 +1,55 @@
# CC.Yi
#### 介绍
基于.NET的MVC三成架构的框架--Yi意框架意义是为了开发更简易
第一版开发完成时间2021/3/19 (请记住,这是一个值得纪念的日子)
为了更简易的开发我们在2021/3/27 加入了vue分支我们将持续更新
#### 软件架构
架构:.NET5 +mysql+sql server后期我们将集成数据+前端Vue让开发更加简易
操作系统WindowsLinux
扩展EFcoreAutofacIdentityCastleRedisSwaggerT4 Nlog后期我们会添加更多
封装Json处理模块滑动验证码模块base64图片处理模块后期我们会添加更多
思想简单工厂模式抽象工厂模式观察者模式面向AOP思想面向对象开发
#### 目录结构
![输入图片说明](https://images.gitee.com/uploads/images/2021/0321/023715_59bef411_3049273.png "屏幕截图.png")
Model模型层first code代码优先添加模型数据自动生成
DAL数据处理层处理数据但并未加载进内存
BLL业务逻辑层数据的逻辑将在这层处理
Common工具层工具人层方法已封装一键调用
API接口层接入Swagger可视化测试接口
#### 安装教程
我们将在之后更新教程手册!
1. 下载全部源码
2. 使用Visual Studio 2019在windows环境中打开CC.Yi.sln文件即可
#### 使用说明
我们将在之后更新教程手册!
1. 添加一个数据库,并修改连接数据库的配置文件
2. 添加模型类使用Add-Migration xxx迁移再使用Update-Database更新数据库
3. 向T4Model添加模型名一键转换生成T4
4. 控制器构造函数进行依赖注入直接使用
#### 联系我们:
QQ454313500

5
T4Model/说明.txt Normal file
View File

@@ -0,0 +1,5 @@
这里存放T4要生成的模型
使用英文的 , 分隔
例如:
student,teacher
点击 生成->转换所有t4模板 即可完成生成