• NetCore 3.1 项目搭建【反射依赖注入,Swagger结合Jwt,sqlSugar+EfCore、异常中间件+Log4Net+MongoDb,Redis+Docker,丰富的公共类库,Filter 过滤器,代码示例】 下载即可用


    十年河东,十年河西,莫欺少年穷

    学无止境,精益求精

    1、通过反射自动注入接口及服务类,项目数据访问层和业务逻辑层分离

    2、数据库操作使用EFCore

    3、sqlSugar 实现数据库复杂查询

    4、实例代码丰富

    5、丰富的公共类库

    6、支持swagger + jwt + 异常中间件 + mongoDb + redis + docker 

    初级版下载地址:https://download.csdn.net/download/bbwolong/81748937

    优化版下载地址:https://download.csdn.net/download/bbwolong/81881080

     简单介绍如下:

     

    示例代码:

    扩展方法:JwtExtension

     public static class JwtExtension
        {
            public static void AddJwt(this IServiceCollection services)
            {
                services.AddAuthentication(x =>
                {
                    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                }).AddJwtBearer(x =>
                {
                    x.RequireHttpsMetadata = false;
                    x.SaveToken = true;
                    x.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(TokenManagementModel.Secret)),
                        ValidIssuer = TokenManagementModel.Issuer,
                        ValidAudience = TokenManagementModel.Audience,
                        ValidateIssuer = false,
                        ValidateAudience = false
                    };
                });
            }
        }
    View Code

    扩展方法Swagger

     public static class SwaggerExtension
        {
            public static void AddSwagger(this IServiceCollection services, string apiName, string title = "", string version="V1")
            {
                services.AddSwaggerGen(c =>
                {
                    // 添加文档信息
                    c.SwaggerDoc(version, new OpenApiInfo
                    {
                        Version = version,
                        Title = title
                    });
                    AddSwagger(apiName, c);
                });
            }
    
    
            public static void AddSwagger(this IServiceCollection services, string apiName, params OpenApiInfo[] infos)
            {
                services.AddSwaggerGen(c =>
                {
                    // 添加文档信息
                    foreach (var item in infos)
                    {
                        c.SwaggerDoc(item.Version, item);
                    }
                    AddSwagger(apiName, c);
                });
            }
    
            private static void AddSwagger(string apiName, SwaggerGenOptions c)
            {
                c.DocumentFilter<HiddenApiFilter>();
                c.DocumentFilter<SwaggerEnumFilter>();
                c.SchemaFilter<HiddenFieldFilter>();
                c.DocInclusionPredicate((docName, apiDesc) => apiDesc.GroupName == docName.ToUpper());
                var basePath = Path.GetDirectoryName(AppContext.BaseDirectory);
                c.IncludeXmlComments(Path.Combine(basePath, $"{apiName}.xml"), true);
                c.IncludeXmlComments(Path.Combine(basePath, Constants.ModelDllXml), true);
    
                #region Jwt
                c.OperationFilter<AddResponseHeadersFilter>();
                c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
                c.OperationFilter<SecurityRequirementsOperationFilter>();
                c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传递)直接在下面框中输入Bearer {token}(注意两者之间是一个空格) \"",
                    Name = "Authorization",//jwt默认的参数名称
                    In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
                    Type = SecuritySchemeType.ApiKey
                });
                #endregion
            }
    
            public static void UseSwag(this IApplicationBuilder app, string version = "V1")
            { 
                // 启用Swagger中间件
                app.UseSwagger(c => c.RouteTemplate = "/swagger/{documentName}/swagger.json");
                // 配置SwaggerUI
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint($"{Constants.VirtualPath}/swagger/{version}/swagger.json", version);
                });
            }
    
            public static void UseSwag(this IApplicationBuilder app, params string[] versions)
            {
                // 启用Swagger中间件
                app.UseSwagger(c => c.RouteTemplate = "/swagger/{documentName}/swagger.json");
                // 配置SwaggerUI
                foreach (var version in versions)
                {
                    app.UseSwaggerUI(c =>
                    {
                        c.SwaggerEndpoint($"{Constants.VirtualPath}/swagger/{version}/swagger.json", version);
                    });
                }
            }
        }
    View Code

    扩展方法:JsonExtension

        public static class JsonExtension
        {
            public static void AddJson(this IServiceCollection services,bool resolver = true)
            {
                services.AddControllersWithViews().AddNewtonsoftJson(options =>
                {
                    if (resolver)
                    {
                        options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                    }
                    options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;  // 设置时区为 UTC)
                    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                });
            }
        }
    View Code

    过滤器:HiddenApiFilter

        public class HiddenApiFilter : IDocumentFilter
        {
            public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
            {
                foreach (var item in context.ApiDescriptions)
                {
                    if (item.TryGetMethodInfo(out MethodInfo methodInfo))
                    {
                        if (methodInfo.ReflectedType.CustomAttributes.Any(t => t.AttributeType == typeof(HiddenAttribute))
                        || methodInfo.CustomAttributes.Any(t => t.AttributeType == typeof(HiddenAttribute)))
                        {
                            var key = "/" + item.RelativePath.TrimEnd('/');
                            if (key.Contains("?"))
                            {
                                int idx = key.IndexOf("?", StringComparison.Ordinal);
                                key = key.Substring(0, idx);
                            }
                            if (swaggerDoc.Paths.ContainsKey(key))
                            {
                                swaggerDoc.Paths.Remove(key);
                            }
                        }
                    }
                }
            }
        }
    
    
        public class HiddenFieldFilter : ISchemaFilter
        {
            public void Apply(OpenApiSchema schema, SchemaFilterContext context)
            {
                if (schema?.Properties == null)
                {
                    return;
                }
                var name = context.Type.FullName;
                var excludedProperties = context.Type.GetProperties();
                foreach (var property in excludedProperties)
                {
                    var attribute = property.GetCustomAttribute<HiddenFieldAttribute>();
                    if (attribute != null
                        && schema.Properties.ContainsKey(property.Name.ToLowerStart()))
                    {
                        schema.Properties.Remove(property.Name.ToLowerStart());
                    }
                };
            }
        }
    View Code

    通过反射依赖注入

    public static class DIRegister
        {
            public static void RegisterDI(this IServiceCollection services)
            {
                var rootPath = Path.GetDirectoryName(typeof(DIExtension).Assembly.Location);
                var rootDir = new DirectoryInfo(rootPath);
                var basePath = rootDir.FullName;
                //注册业务访问层    接口 与 实现类 注册为 AddScoped
                RegisterDll(services, basePath, Constants.ServiceDllFullName, Constants.ServiceSuffix );
                //注册数据访问层  接口 与 实现类 注册为 AddScoped
                RegisterDll(services, basePath, Constants.RepositoryDllFullName, Constants.RepositorySuffix );
            }
    
            private static void RegisterDll(IServiceCollection services, string basePath, string dllName, params string[] endsWith)
            {
                ///D:\525gitProject\netcore\WuAnManager\WuAnChangeApi\bin\Debug\netcoreapp3.1\WuAnService.dll
                string assemblyPath = Path.Combine(basePath, dllName);
                var assembly = Assembly.LoadFrom(assemblyPath);
                services.RegisterAssemblyEndsWith(assembly, endsWith);
            }
    
            public static void DIListPage(this IApplicationBuilder app, IServiceCollection _services)
            {
                app.Map($"/api/allservices", builder => builder.Run(async context =>
                {
                    var sb = new StringBuilder();
                    sb.Append("<h1>All Services</h1>");
                    sb.Append("<table><thead>");
                    sb.Append("<tr><th>Type</th><th>Lifetime</th><th>Instance</th></tr>");
                    sb.Append("</thead><tbody>");
                    foreach (var svc in _services)
                    {
                        sb.Append("<tr>");
                        sb.Append($"<td>{svc.ServiceType.FullName}</td>");
                        sb.Append($"<td>{svc.Lifetime}</td>");
                        sb.Append($"<td>{svc.ImplementationType?.FullName}</td>");
                        sb.Append("</tr>");
                    }
                    sb.Append("</tbody></table>");
                    await context.Response.WriteAsync(sb.ToString());
                }));
            }
        }
    View Code

    异常处理中间件

        public class ExceptionMiddlewares
        {
            private ILog log;
            private readonly RequestDelegate next;
            private IHostingEnvironment environment;
    
            public ExceptionMiddlewares(RequestDelegate next, IHostingEnvironment environment)
            {
                this.log = LogManager.GetLogger(Startup.repository.Name, typeof(ExceptionMiddlewares));
                this.next = next;
                this.environment = environment;
            }
    
            public async Task Invoke(HttpContext context)
            {
                try
                {
                    await next.Invoke(context);
                    var features = context.Features;
                }
                catch(AssertException ex)
                {
                    if (context.Response.HasStarted)
                    {
                        throw;
                    }
                    await Response(context, ex.HttpStatusCode, ex.Message);
                }
                catch (Exception e)
                {
                    Log.Inst.Error($"wuanapi系统异常:{e.ToString()}");
                    await HandleException(context, e);
                }
            }
    
            private async Task HandleException(HttpContext context, Exception e)
            {
                context.Response.StatusCode = 500;
                context.Response.ContentType = "text/json;charset=utf-8;";
                string error = "";
    
                var json = new { message = e.Message };
                log.Error(json);
                error = JsonConvert.SerializeObject(json);
    
    
                await context.Response.WriteAsync(error);
            }
    
            private async Task Response(HttpContext httpContext, int statusCode, string message)
            {
                httpContext.Response.StatusCode = statusCode;
                httpContext.Response.ContentType = "application/json; charset=utf-8";
                var result = CommonBaseResponse.SetResponse(false, message);
                await httpContext.Response.WriteAsync(result.ToJson());
            }
        }
    View Code

    SqlSugar 帮助类

     public class DataRepository
        {
            public static string NewGuid()
            {
                return Guid.NewGuid().ToString("N");
            }
            /// <summary>
            /// 获取返回的列表
            /// </summary>
            /// <typeparam name="U"></typeparam>
            /// <param name="sql"></param>
            /// <param name="orderby"></param>
            /// <returns></returns>
            public static List<U> GetListBySql<U>(string sql, string orderby = "")
                where U : class, new()
            {
                SugarContext sugar = new SugarContext();
                List<U> result = null;
                using (var db = sugar.Db)
                {
                    if (string.IsNullOrEmpty(orderby))
                    {
                        result = db.SqlQueryable<U>(sql).ToList();
                    }
                    else
                    {
                        result = db.SqlQueryable<U>(sql).OrderBy(orderby).ToList();
                    }
                }
                return result;
            }
            /// <summary>
            /// 获取返回的列表-参数化
            /// </summary>
            /// <typeparam name="U"></typeparam>
            /// <param name="sql"></param>
            /// <param name="where"></param>
            /// <param name="parameters"></param>
            /// <returns></returns>
            public static List<U> GetListBySql<U>(string sql, string where, object parameters)
                where U : class, new()
            {
                SugarContext sugar = new SugarContext();
                List<U> result = null;
                using (var db = sugar.Db)
                {
                    result = db.SqlQueryable<U>(sql).Where(where, parameters).ToList();
                }
                return result;
            }
    
            /// <summary>
            /// 获取DbSet 第一行
            /// </summary>
            /// <typeparam name="U"></typeparam>
            /// <param name="sql"></param>
            /// <returns></returns>
            public static U GetOneBySql<U>(string sql)
                where U : class, new()
            {
                SugarContext sugar = new SugarContext();
                U result = null;
                using (var db = sugar.Db)
                {
                    result = db.SqlQueryable<U>(sql).First();
                }
                return result;
            }
            /// <summary>
            /// 获取第一行第一列的值 并转化为Int
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public static int GetInt(string sql)
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return db.Ado.GetInt(sql);
                }
            }
            /// <summary>
            /// 获取第一行第一列的值 并转化为Double
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public static double GetDouble(string sql)
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return db.Ado.GetDouble(sql);
                }
            }
            /// <summary>
            /// 执行Sql 查询单个实体
            /// </summary>
            /// <typeparam name="E"></typeparam>
            /// <typeparam name="U"></typeparam>
            /// <param name="sql"></param>
            /// <param name="OrderBy"></param>
            /// <param name="u"></param>
            /// <returns></returns>
            public static E PageOne<E>(string sql)
                where E : class, new()
            {
                SugarContext sugar = new SugarContext();
                var db = sugar.Db;
                var one = db.SqlQueryable<E>(sql).ToList().FirstOrDefault();
                return one;
            }
    
            /// <summary>
            /// 查询结果List的第一条记录
            /// </summary>
            /// <typeparam name="E"></typeparam>
            /// <param name="sql"></param>
            /// <param name="where"></param>
            /// <param name="parameters"></param>
            /// <returns></returns>
            public static E PageOne<E>(string sql, string where, object parameters)
               where E : class, new()
            {
                SugarContext sugar = new SugarContext();
                if (parameters == null)
                {
                    return PageOne<E>(sql);
                }
    
                var db = sugar.Db;
                var one = db.SqlQueryable<E>(sql).Where(where, parameters).ToList().FirstOrDefault();
                return one;
            }
    
            public static PaginationListModel<E> PageQuery<E, U>(string sql, string OrderBy, U u)
              where U : PaginationModel
              where E : class, new()
            {
                SugarContext sugar = new SugarContext();
                var db = sugar.Db;
                int total = 0;
                List<E> list = null;
                if (OrderBy.IsNullOrWhiteSpace())
                {
                    list = db.SqlQueryable<E>(sql).ToPageList(u.pageNumber, u.pageSize, ref total);
                }
                else
                {
                    list = db.SqlQueryable<E>(sql).OrderBy(OrderBy).ToPageList(u.pageNumber, u.pageSize, ref total);
                }
                return new PaginationListModel<E>()
                {
                    data = list,
                    pagination = new BasePaginationModel()
                    {
                        pageNumber = u.pageNumber,
                        pageSize = u.pageSize,
                        total = total
                    }
                };
            }
    
    
            /// <summary>
            /// 第一行第一列
            /// </summary>
            /// <param name="sql"></param>
            /// <param name="parameters"></param>
            /// <returns></returns>
            public static object ExecuteScalar(string sql, object parameters = null)
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return db.Ado.GetScalar(sql, parameters);
                }
            }
    
            /// <summary>
            /// 执行Update insert 等操作
            /// </summary>
            /// <param name="sql"></param>
            /// <param name="parameters"></param>
            /// <returns></returns>
            public static int ExecuteCommand(string sql, object parameters = null)
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return db.Ado.ExecuteCommand(sql, parameters);
                }
            }
    
            /// <summary>
            /// 第一行第一列
            /// </summary>
            public static object ExecuteScalar(string sql)
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return db.Ado.GetScalar(sql);
                }
            }
            /// <summary>
            /// 第一行第一列    -    异步
            /// </summary>
            public static async Task<object> ExecuteScalarAsync(string sql, object parameters = null)
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return await db.Ado.GetScalarAsync(sql, parameters);
                }
            }
            /// <summary>
            /// 第一行第一列    -    异步
            /// </summary>
            public static async Task<object> ExecuteScalarAsync(string sql)
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return await db.Ado.GetScalarAsync(sql);
                }
            }
    
            public static E GetOneBySql<E>(string sql, object parameters = null)
                where E : class
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return db.Ado.SqlQuerySingle<E>(sql, parameters);
                }
    
            }
            /// <summary>
            /// 第一行第一列    -    异步
            /// </summary>
            public static async Task<E> GetOneBySqlAsync<E>(string sql, object parameters = null)
              where E : class
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return await db.Ado.SqlQuerySingleAsync<E>(sql, parameters);
                }
    
            }
    
            public static List<E> GetBySql<E>(string sql, object parameters = null)
                where E : class
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return db.Ado.SqlQuery<E>(sql, parameters);
                }
    
            }
    
            public static async Task<List<E>> GetBySqlAsync<E>(string sql, object parameters = null)
                where E : class
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    return await db.Ado.SqlQueryAsync<E>(sql, parameters);
                }
            }
    
            /// <summary>
            /// 执行事务
            /// </summary>
            /// <param name="sqls"></param>
            public static void ExecTransaction(List<string> sqls)
            {
                SugarContext sugar = new SugarContext();
                using (var db = sugar.Db)
                {
                    try
                    {
                        db.Ado.BeginTran();
                        foreach (var item in sqls)
                        {
                            db.Ado.ExecuteCommand(item);
                        }
                        db.Ado.CommitTran();
    
                    }
                    catch (Exception ex)
                    {
                        db.Ado.RollbackTran();
                        throw ex;
                    }
                }
            }
    
        }
    
        public class DataRepository<T> where T   : class, new()
        {
    
            public static PaginationListModel<T>  PageQuery<U>(string sql, U u, string where = "")
              where U : OrderByPaginationModel 
            {
                SugarContext sugar = new SugarContext();
                var db = sugar.Db;
                var query = db.SqlQueryable<T>(sql);
                if (where.NotNullOrWhiteSpace())
                {
                    query = query.Where(where, u.ToSqlParam());
                }
                if (u.OrderBy.NotNullOrWhiteSpace())
                {
                    query = query.OrderBy(u.OrderBy);
                }
                int total = 0;
                var list = query.ToPageList(u.pageNumber, u.pageSize, ref total);
                return new PaginationListModel<T>()
                {
                    data = list,
                    pagination = new BasePaginationModel()
                    {
                        pageNumber = u.pageNumber,
                        pageSize = u.pageSize,
                        total = total
                    }
                };
            }
    
        }
    
        internal static class SqlExtend
        {
            public static string Equal(this string source, string field)
            {
                return $"{source} = {field}";
            }
    
            public static string Like(this string source)
            {
                return $"%{source}%";
            }
    
            public static Dictionary<string, object> ToSqlParam<T>(this T t)
                where T : class
            {
                var fields = typeof(T).GetProperties();
                var fieldDict = new Dictionary<string, object>();
                foreach (var item in fields)
                {
                    fieldDict.Add(item.Name, item.GetValue(t));
                }
                return fieldDict;
            }
    
            public static List<Dictionary<string, object>> ToSqlParam<T>(this List<T> tList)
              where T : class
            {
                var result = new List<Dictionary<string, object>>();
                foreach (var item in tList)
                {
                    result.Add(ToSqlParam(item));
                }
                return result;
            }
    
            public static string Top(this string source, int topCount)
            {
                return source.Replace("select", $"select top {topCount}");
            }
    
            public static string Where(this string source, params string[] conditions)
            {
                var where = new StringBuilder(" where 1 = 1 ");
                foreach (var item in conditions)
                {
                    where.Append($" and {item} ");
                }
                return $"{source} {where}";
            }
    
    
        }
    View Code

    sqlSugarDbContxt上下文

        public class SugarContext
        {
            /// 获取连接字符串        
            private static string Connection = ConfigCommon.Get("WuAnFundDbContext");
            public SugarContext(string connection = "")
            {
                Db = new SqlSugarClient(new ConnectionConfig()
                {
                    ConnectionString = connection.IsNullOrWhiteSpace() ? Connection : connection,
                    DbType = DbType.SqlServer,
                    InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
                    IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了
    
                });
                //调式代码 用来打印SQL 
                Db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    Console.WriteLine(sql + "\r\n" +
                        Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
                    Console.WriteLine();
                };
    
            }
            //注意:不能写成静态的
            public SqlSugarClient Db;//用来处理事务多表查询和复杂的操作
        }
    View Code

    数据访问层代码示例1

        /// <summary>
        /// 数据库访问层 
        /// </summary>
    
        public class StudentRepository: IStudentRepository
        {
            public List<StudentModel> GetStudents()
            {
                string sql = "select * from Student where StudentAge<100 order by StudentAge";
                return DataRepository.GetBySql<StudentModel>(sql);
            }
    
            public List<StudentModel> GetStudentsByName(SearchStudentByNameModel searchParam)
            {
                string sql = "select * from Student where 1=1 ";
                if (!string.IsNullOrEmpty(searchParam.StudentName))
                {
                    sql += " and StudentName=@StudentName";
                }
                var parm = new { StudentName = searchParam.StudentName };
                return DataRepository.GetBySql<StudentModel>(sql, parm);
            }
    
            public PaginationListModel<StudentModel> GetPaginationStudents(SearchStudentModel searchParam)
            {   
                string sql = string.Format(@"SELECT * FROM [dbo].[Student] ");
                string where = " 1=1 and StudentName<>@StudentName";
                searchParam.OrderBy = "createTime desc";
                return DataRepository<StudentModel>.PageQuery <SearchStudentModel>(sql, searchParam, where);
            }
    
    
            public PaginationListModel<StudentModel> GetPageStudents(SearchStudentModel_2 searchParam)
            {
                string sql = string.Format(@"SELECT * FROM [dbo].[Student] where 1=1  ");
                 sql+= " and StudentName<>'"+ searchParam .StudentName+ "'";
    
                return DataRepository.PageQuery<StudentModel, SearchStudentModel_2>(sql, "CreateTime desc", searchParam);
            }
        }
    View Code

    等等吧,中小企业项目用这个框架完全没问题

    @天才卧龙的博客

  • 相关阅读:
    JQuery 快速入门一篇通
    Winform 显示Gif图片
    MD5编码工具类 MD5Code.java
    Asp.Net 上传图片并生成高清晰缩略图
    winform时钟c#代码
    PHP面试题汇总
    PHP条件语句语法与示例
    Android声音播放实例代码
    html和js基础功能代码备份
    纯C#实现屏幕指定区域截屏
  • 原文地址:https://www.cnblogs.com/chenwolong/p/NetCoreDIRgist.html
Copyright © 2020-2023  润新知