public static IServiceCollection AddSenparcEntitiesDI(this IServiceCollection services)
        {
            //var connectionString = Senparc.Scf.Core.Config.SenparcDatabaseConfigs.ClientConnectionString;
            //services.AddDbContext<SenparcEntities>(options => options.UseSqlServer(connectionString, b => b.MigrationsAssembly("Senparc.Web")));

            /* 参考信息
             *      错误信息:
             *          中文:EnableRetryOnFailure 解决短暂的数据库连接失败
             *          英文:Win32Exception: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
             *                InvalidOperationException: An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseSqlServer' call.
             *      问题解决方案说明:https://www.colabug.com/2329124.html
             */

            services.AddScoped(s => new SenparcEntities(new DbContextOptionsBuilder <SenparcEntities>()
                                                        .UseSqlServer(Scf.Core.Config.SenparcDatabaseConfigs.ClientConnectionString)
                                                        .Options));
            //#if DEBUG
            //            var connectionString = Senparc.Scf.Core.Config.SenparcDatabaseConfigs.ClientConnectionString;
            //            services.AddDbContext<SenparcEntities>(options => options.UseSqlServer(connectionString, b => b.MigrationsAssembly("Senparc.Web")));
            //#else
            //            services.AddScoped(s => new SenparcEntities(new DbContextOptionsBuilder<SenparcEntities>()
            //                .UseSqlServer(Config.SenparcDatabaseConfigs.ClientConnectionString)
            //                .Options));
            //#endif

            SenparcDI.ResetGlobalIServiceProvider();//清空缓存,下次使用DI会自动重新Build

            return(services);
        }
        /// <summary>
        /// 注册 IServiceCollection,并返回 RegisterService,开始注册流程(必须)
        /// </summary>
        /// <param name="serviceCollection">IServiceCollection</param>
        /// <param name="certName">证书名称,必须全局唯一,并且确保在全局 HttpClientFactory 内唯一</param>
        /// <param name="cert">证书对象,也可以是 X509Certificate2</param>
        /// <param name="checkValidationResult">设置</param>
        /// <returns></returns>
        public static IServiceCollection AddSenparcHttpClientWithCertificate(this IServiceCollection serviceCollection,
                                                                             string certName, X509Certificate cert, bool checkValidationResult = false)
        {
            serviceCollection.AddHttpClient <SenparcHttpClient>(certName)
            .ConfigurePrimaryHttpMessageHandler(() =>
            {
                var httpClientHandler = HttpClientHelper.GetHttpClientHandler(null, RequestUtility.SenparcHttpClientWebProxy, System.Net.DecompressionMethods.GZip);

                httpClientHandler.ClientCertificates.Add(cert);

                if (checkValidationResult)
                {
                    httpClientHandler.ServerCertificateCustomValidationCallback = new Func <HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool>(RequestUtility.CheckValidationResult);
                }

                return(httpClientHandler);
            });

            SenparcDI.ResetGlobalIServiceProvider();//重置 GlobalIServiceProvider
            return(serviceCollection);
        }
        public static IServiceCollection AddSenparcEntitiesDI(this IServiceCollection services)
        {
            //var connectionString = Senparc.Scf.Core.Config.SenparcDatabaseConfigs.ClientConnectionString;
            //services.AddDbContext<SenparcEntities>(options => options.UseSqlServer(connectionString, b => b.MigrationsAssembly("Senparc.Web")));

            services.AddScoped(s => new SenparcEntities(new DbContextOptionsBuilder <SenparcEntities>()
                                                        .UseSqlServer(Scf.Core.Config.SenparcDatabaseConfigs.ClientConnectionString)
                                                        .Options));
            //#if DEBUG
            //            var connectionString = Senparc.Scf.Core.Config.SenparcDatabaseConfigs.ClientConnectionString;
            //            services.AddDbContext<SenparcEntities>(options => options.UseSqlServer(connectionString, b => b.MigrationsAssembly("Senparc.Web")));
            //#else
            //            services.AddScoped(s => new SenparcEntities(new DbContextOptionsBuilder<SenparcEntities>()
            //                .UseSqlServer(Config.SenparcDatabaseConfigs.ClientConnectionString)
            //                .Options));
            //#endif

            SenparcDI.ResetGlobalIServiceProvider();//清空缓存,下次使用DI会自动重新Build

            return(services);
        }
Exemple #4
0
        /// <summary>
        /// 注册TenPayV3Info信息
        /// </summary>
        /// <param name="tenPayV3Info"></param>
        /// <param name="name">公众号唯一标识(或名称)</param>
        public static void Register(TenPayV3Info tenPayV3Info, string name)
        {
            var key = GetKey(tenPayV3Info.MchId, tenPayV3Info.Sub_MchId);

            Data[key] = tenPayV3Info;

            //添加到全局变量
            if (!name.IsNullOrEmpty())
            {
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_AppId              = tenPayV3Info.AppId;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_AppSecret          = tenPayV3Info.AppSecret;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_MchId              = tenPayV3Info.MchId;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_Key                = tenPayV3Info.Key;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_CertPath           = tenPayV3Info.CertPath;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_CertSecret         = tenPayV3Info.CertSecret;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_TenpayNotify       = tenPayV3Info.TenPayV3Notify;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_WxOpenTenpayNotify = tenPayV3Info.TenPayV3_WxOpenNotify;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_SubMchId           = tenPayV3Info.Sub_MchId;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_SubAppId           = tenPayV3Info.Sub_AppId;
                Senparc.Weixin.Config.SenparcWeixinSetting.Items[name].TenPayV3_SubAppSecret       = tenPayV3Info.Sub_AppSecret;
            }

            //进行证书注册
#if NETSTANDARD2_0 || NETCOREAPP3_0
            try
            {
                var service      = SenparcDI.GlobalServiceCollection;
                var certName     = key;
                var certPassword = tenPayV3Info.CertSecret;
                var certPath     = tenPayV3Info.CertPath;

                //添加注册

                //service.AddSenparcHttpClientWithCertificate(certName, certPassword, certPath, false);

                #region 测试添加证书

                //添加注册

                if (!string.IsNullOrEmpty(certPath))
                {
                    if (File.Exists(certPath))
                    {
                        try
                        {
                            var cert = new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);
                            var checkValidationResult = false;

                            var serviceCollection = SenparcDI.GlobalServiceCollection;
                            //serviceCollection.AddHttpClient<SenparcHttpClient>(certName)
                            serviceCollection.AddHttpClient(certName)
                            .ConfigurePrimaryHttpMessageHandler(() =>
                            {
                                var httpClientHandler = HttpClientHelper.GetHttpClientHandler(null, RequestUtility.SenparcHttpClientWebProxy, System.Net.DecompressionMethods.None);

                                httpClientHandler.ClientCertificates.Add(cert);

                                if (checkValidationResult)
                                {
                                    httpClientHandler.ServerCertificateCustomValidationCallback = new Func <HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool>(RequestUtility.CheckValidationResult);
                                }

                                return(httpClientHandler);
                            });
                        }
                        catch (Exception ex)
                        {
                            Senparc.CO2NET.Trace.SenparcTrace.SendCustomLog($"添加微信支付证书发生异常", $"certName:{certName},certPath:{certPath}");
                            Senparc.CO2NET.Trace.SenparcTrace.BaseExceptionLog(ex);
                        }
                    }
                    else
                    {
                        Senparc.CO2NET.Trace.SenparcTrace.SendCustomLog($"已设置微信支付证书,但无法找到文件", $"certName:{certName},certPath:{certPath}");
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                throw;
            }
            finally {
                SenparcDI.ResetGlobalIServiceProvider();
            }
#endif
        }
        public void ThreadAndGlobalServiceTest()
        {
            BaseTest.RegisterServiceCollection();
            BaseTest.RegisterServiceStart(true);

            SenparcDI.GlobalServiceCollection.AddScoped <SenparcSetting>();
            SenparcDI.ResetGlobalIServiceProvider();

            //测试跨线程唯一
            var s = SenparcDI.GetService <SenparcSetting>(true);

            Console.WriteLine($"s:{s.GetHashCode()}");

            var threadsCount = 10;

            Console.WriteLine("======= 开始全局唯一测试 =======");
            var finishedThread = 0;

            for (int i = 0; i < threadsCount; i++)
            {
                var index  = i;
                var thread = new Thread(() =>
                {
                    var s1 = SenparcDI.GetService <SenparcSetting>(true);
                    var s2 = SenparcDI.GetService <SenparcSetting>(true);
                    Console.WriteLine("ServiceProcider:" + SenparcDI.GlobalIServiceProvider?.GetHashCode());
                    Console.WriteLine($"{index}:{s1.GetHashCode()}");
                    Console.WriteLine($"{index}:{s2.GetHashCode()}");
                    Assert.AreEqual(s1.GetHashCode(), s2.GetHashCode());
                    finishedThread++;
                });
                thread.Start();
            }

            while (finishedThread != threadsCount)
            {
            }
            //所有HashCode相同

            //测试通线程唯一
            Console.WriteLine("======= 开始线程内唯一测试 =======");
            finishedThread = 0;
            for (int i = 0; i < threadsCount; i++)
            {
                var thread = new Thread(() =>
                {
                    var index = i;
                    Console.WriteLine($"-------{index}----------");

                    var threadScope = Thread.GetData(Thread.GetNamedDataSlot(CO2NET.SenparcDI.SENPARC_DI_THREAD_SERVICE_Scope)) as IServiceScope;
                    Console.WriteLine("ServiceScope:" + threadScope?.GetHashCode());
                    Console.WriteLine("ServiceProcider:" + threadScope?.ServiceProvider.GetHashCode());

                    var s1 = SenparcDI.GetService <SenparcSetting>(false);
                    var s2 = SenparcDI.GetService <SenparcSetting>(false);
                    Console.WriteLine($"{index}:{s1.GetHashCode()}");
                    Console.WriteLine($"{index}:{s2.GetHashCode()}");
                    Assert.AreEqual(s1.GetHashCode(), s2.GetHashCode());

                    threadScope = Thread.GetData(Thread.GetNamedDataSlot(CO2NET.SenparcDI.SENPARC_DI_THREAD_SERVICE_Scope)) as IServiceScope;
                    Console.WriteLine("ServiceScope:" + threadScope.GetHashCode());
                    Console.WriteLine("ServiceProcider:" + threadScope.ServiceProvider.GetHashCode());
                    Console.WriteLine("-----------------");
                    finishedThread++;
                });
                thread.Start();
            }

            while (finishedThread != threadsCount)
            {
            }
            //单线程内HashCode相同
        }