ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

NetCore 3.1 项目搭建【反射依赖注入,Swagger结合Jwt,sqlSugar+EfCore、异常中间件+Log4Net+MongoDb,Redis+Docker,丰富的公共类库,代码示例

2022-02-22 10:00:08  阅读:214  来源: 互联网

标签:类库 string 示例 db 中间件 sql var new public


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

学无止境,精益求精

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

2、数据库操作使用EFCore

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

4、实例代码丰富

5、丰富的公共类库

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

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

 简单介绍如下:

 

 

示例代码:

扩展方法: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

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

@天才卧龙的博客

标签:类库,string,示例,db,中间件,sql,var,new,public
来源: https://www.cnblogs.com/chenwolong/p/NetCoreDIRgist.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有