using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.Linq; using System.Reflection; using XYY.Core.Standard.ExcelHelper.MSExcelHelper; using XYY.Core.Standard.AliYun; using XYY.Core.Standard.Data.Infrastructure; using EasyNetQ; using XYY.TaskTrack.Standard; using Serilog; using StackExchange.Redis; using XYY.Core.Standard.Data.Redis; using XYY.Core.Standard.FiddlerClient; namespace XYY.Service.Standard.RegionService { public enum DistributedCacheType { Memory = 0, Redis = 1 } public class ServiceOption { public bool NoService { get; set; } public string PBESConnection { get; set; } public string MsgESConnection { get; set; } /// /// 是否开启缓存 /// public DistributedCacheType CacheType { get; set; } /// /// 是否使用事务支持 /// public bool USEDBTransferAsMVC { get; set; } /// /// 传入连接并启用头程信息 /// public string FirstESConnection { get; set; } /// /// 手动补充头程数据 /// public string FirstESConnection2 { get; set; } /// /// 是否启用Rebbit /// public bool UseRabbit { get; set; } public string FinanceChargesRedisConnection { get; set; } public string RedisConnection { get; set; } public bool UseTrackingPUSHRedis { get; set; } public bool UseFinanceChargesRedis { get; set; } public string SqlServiceConnection { get; set; } public AliYunConfig AliYunConfig { get; set; } public bool OpenChannelApi { get; set; } /// /// 开启捕获 /// public bool UseFiddler { get; set; } } public static class DefaultConfig { /// /// DBConnectionStrings:SqlService /// public static string SqlServiceConnectionKey => "DBConnectionStrings:SqlService"; public static string ESUrlKey => "DBConnectionStrings:ESUrl"; public static string AliYunBucketName => "aliyun:AliYunBucketName"; public static string AliYunEndPoint => "aliyun:aliYunEndPoint"; public static string AliYunKeyId => "aliyun:aliYunKeyId"; public static string AliYunKeySecret => "aliyun:aliYunKeySecret"; public static string AliYunBasePath => "aliyun:BasePath"; public static string AliYunPubEndPoint => "aliyun:aliYunPubEndPoint"; public static string RabbitConnectionKey => "DBConnectionStrings:RabbitConnection"; public static string RedisConnectionKey => "DBConnectionStrings:RedisCacheUrl"; } public static class ServiceRegion { public static IServiceCollection AddDataService(this IServiceCollection services) { #region 依赖注入 //services.AddScoped(); string[] regeionTypes = new string[] { "XYY.Data.Standard.dll", "XYY.Data.Standard.User.dll", "XYY.Data.Standard.Customer.dll", "XYY.Data.Standard.Charging.dll" }; var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = System.IO.Directory.GetFiles(path, "*.dll").Where(x => regeionTypes.Contains(System.IO.Path.GetFileName(x))) .Select(Assembly.LoadFrom).ToArray(); var types = referencedAssemblies .SelectMany(a => a.DefinedTypes) .Select(type => type.AsType()) .Where(x => x.Name.EndsWith("Repository") ).ToArray(); var implementTypes = types.Where(x => x.IsClass).ToArray(); var interfaceTypes = types.Where(x => x.IsInterface).ToArray(); foreach (var implementType in implementTypes) { var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType)); if (interfaceType != null) services.AddScoped(interfaceType, implementType); } #endregion return services; } public static IServiceCollection AddAliyunService(this IServiceCollection services, IConfiguration Configuration) { if (!string.IsNullOrEmpty(Configuration[DefaultConfig.AliYunPubEndPoint])) { var AliYunConfig = new Core.Standard.AliYun.AliYunConfig { AliYunBucketName = Configuration[DefaultConfig.AliYunBucketName], AliYunEndPoint = Configuration[DefaultConfig.AliYunEndPoint], AliYunKeyId = Configuration[DefaultConfig.AliYunKeyId], AliYunKeySecret = Configuration[DefaultConfig.AliYunKeySecret], BasePath = Configuration[DefaultConfig.AliYunBasePath], CDNEndPoint = Configuration[DefaultConfig.AliYunPubEndPoint], }; services.AddSingleton(x => new AliYunPostFileSerivce(AliYunConfig)); } return services; } /// /// 添加Service层注入 /// /// /// XYY.Service.Standard.{serviceName} /// public static IServiceCollection AddStandardService(this IServiceCollection services, string serviceName) { var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = System.IO.Directory.GetFiles(path, $"XYY.Service.Standard.{serviceName}.dll") .Where(x => !System.IO.Path.GetFileName(x).Equals("XYY.Service.Standard.RegionService.dll")) .Select(Assembly.LoadFrom).ToArray(); var types = referencedAssemblies .SelectMany(a => a.DefinedTypes) .Select(type => type.AsType()) .Where(x => x.Name.EndsWith("Service") || x.Name.EndsWith("Api") ).ToArray(); var implementTypes = types.Where(x => x.IsClass).ToArray(); var interfaceTypes = types.Where(x => x.IsInterface).ToArray(); foreach (var implementType in implementTypes) { var allInterfaceTypes = interfaceTypes.Where(x => x.IsAssignableFrom(implementType)); if (allInterfaceTypes?.Any() == true) { foreach (var interfaceType in allInterfaceTypes) { services.AddScoped(interfaceType, implementType); } } } return services; } /// 若需要支持事务服务、方法计时服务请配置 spectCore.Extensions.DependencyInjection 框架 /// 启动项添加配置: UseServiceProviderFactory(x => new DynamicProxyServiceProviderFactory()) public static IServiceCollection AddXYYService(this IServiceCollection services, ServiceOption serviceOption, IConfiguration Configuration) { if (!string.IsNullOrEmpty(Configuration[DefaultConfig.AliYunPubEndPoint])) { serviceOption.AliYunConfig = new Core.Standard.AliYun.AliYunConfig { AliYunBucketName = Configuration[DefaultConfig.AliYunBucketName], AliYunEndPoint = Configuration[DefaultConfig.AliYunEndPoint], AliYunKeyId = Configuration[DefaultConfig.AliYunKeyId], AliYunKeySecret = Configuration[DefaultConfig.AliYunKeySecret], BasePath = Configuration[DefaultConfig.AliYunBasePath], CDNEndPoint = Configuration[DefaultConfig.AliYunPubEndPoint], }; } if (serviceOption != null && serviceOption.AliYunConfig != null) { //阿里云 services.AddSingleton(x => new AliYunPostFileSerivce(serviceOption.AliYunConfig)); } //excel services.AddSingleton(); if (serviceOption != null && !string.IsNullOrEmpty(serviceOption.PBESConnection)) { //pb //services.AddSingleton(x => new ESPerformanceDB(serviceOption.PBESConnection)); } if (serviceOption != null && serviceOption.UseRabbit) { //Rebbit服务注册 try { services.AddSingleton(x => RabbitHutch.CreateBus(Configuration[DefaultConfig.RabbitConnectionKey])); services.AddSingleton(); } catch (Exception ex) { Log.Error("服务注册失败" + ex.Message); } } if (serviceOption != null) { //缓存 switch (serviceOption.CacheType) { case DistributedCacheType.Memory: services.AddDistributedMemoryCache(); break; case DistributedCacheType.Redis: services.AddDistributedRedisCache(x => { x.Configuration = serviceOption.RedisConnection; x.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions { Password = "12345", }; x.ConfigurationOptions.EndPoints.Add(serviceOption.RedisConnection); }); break; } //缓存 } //计费缓存 if (serviceOption != null && serviceOption.UseFinanceChargesRedis) { services.AddSingleton(x => new RedisHelper(serviceOption.FinanceChargesRedisConnection, "FinanceChargesRedis", "r-wz9o30bx758o8jhbra:100Ep*dp", 2)); } if (serviceOption != null && serviceOption.UseTrackingPUSHRedis) { services.AddSingleton(x => new RedisHelper(serviceOption.RedisConnection, "TrackingPUSHRedis", "r-wz9o30bx758o8jhbra:100Ep*dp", 3)); } if (serviceOption != null && !string.IsNullOrEmpty(serviceOption.SqlServiceConnection)) { //数据 services.AddDB(serviceOption.SqlServiceConnection); AddDataService(services); } if (serviceOption != null && serviceOption.USEDBTransferAsMVC) { //事务 services.ConfigAspectCore("Repository"); services.AddMvcCore(x => { x.Filters.Add(); x.Filters.Add(); }); } if (serviceOption == null || !serviceOption.NoService) { try { var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = System.IO.Directory.GetFiles(path, "XYY.Service.Standard.*.dll") .Where(x => !System.IO.Path.GetFileName(x).Equals("XYY.Service.Standard.RegionService.dll")) .Select(Assembly.LoadFrom).ToArray(); var types = referencedAssemblies .SelectMany(a => a.DefinedTypes) .Select(type => type.AsType()) .Where(x => x.Name.EndsWith("Service") || x.Name.EndsWith("Api") ).ToArray(); var implementTypes = types.Where(x => x.IsClass).ToArray(); var interfaceTypes = types.Where(x => x.IsInterface).ToArray(); foreach (var implementType in implementTypes) { if (implementType.FullName == "XYY.Service.Standard.ChannelApi.Ultidel.Api") { } //var dd = interfaceTypes.Where(x => x.IsAssignableFrom(implementType)); var allInterfaceTypes = interfaceTypes.Where(x => x.IsAssignableFrom(implementType)); if (allInterfaceTypes?.Any() == true) { foreach (var interfaceType in allInterfaceTypes) { services.AddScoped(interfaceType, implementType); } } } } catch { } } //更改注入方式,注意需要取消订单的api,仅使用Repository 不用services,不能产生依赖关系 //注入处理比较麻烦,尽可能让api纯净 if (serviceOption == null || serviceOption.OpenChannelApi) { string[] regeionTypes = new string[] { "XYY.Data.Standard.dll", "XYY.Service.Standard.ChannelApi.dll", }; string[] fullNames = new string[] { "XYY.Data.Standard.Order", "XYY.Data.Standard.Channel", "XYY.Service.Standard.ChannelApi.Frayun.Api", "XYY.Service.Standard.ChannelApi.SKPB.Api", "XYY.Service.Standard.ChannelApi.MIQ.Api", "XYY.Service.Standard.ChannelApi.Winit.LMAApi", "XYY.Service.Standard.ChannelApi.Winit.ISPApi", "XYY.Service.Standard.ChannelApi.Ultidel" }; var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = System.IO.Directory.GetFiles(path, "*.dll") .Where(x => regeionTypes.Contains(System.IO.Path.GetFileName(x))) .Select(Assembly.LoadFrom).ToArray(); var types = referencedAssemblies .SelectMany(a => a.DefinedTypes) .Select(type => type.AsType()) .Where(x => fullNames.Any(p => x.FullName.Contains(p)) || x.Name.Contains("IBaseApi") ).ToArray(); var implementTypes = types.Where(x => x.IsClass).ToArray(); var interfaceTypes = types.Where(x => x.IsInterface).ToArray(); foreach (var implementType in implementTypes) { var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType)); if (interfaceType != null) services.AddSingleton(interfaceType, implementType); } } var fiddlerLog = new LoggerConfiguration() .MinimumLevel.Warning() .MinimumLevel.Override("LogginService", Serilog.Events.LogEventLevel.Warning) .Enrich.FromLogContext() .WriteTo.Seq("http://47.244.232.78:5341/") .WriteTo.Debug().CreateLogger(); services.AddLogging(logging => { logging.AddSerilog(fiddlerLog); }); //注入访问监听 if (serviceOption != null && serviceOption.UseFiddler) { services.AddSingleton(); } return services; } } }