From 5ec6a8c26cb21943f2c24e27ca93ac2323ebd916 Mon Sep 17 00:00:00 2001
From: bicijinlian <bicijinlian@163.com>
Date: Wed, 21 Dec 2022 03:19:17 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=9A=E9=85=8D=E7=BD=AE?=
 =?UTF-8?q?=E6=BA=90=E5=90=8C=E6=AD=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Options/AppOption.cs                      | 26 ++++++
 .../Options/ReceiveMailOption.cs              | 24 +++++
 ...Pattern.Sutdy.Experience.ConsoleApp.csproj |  9 ++
 .../Program.cs                                | 87 ++++++++++++++++++-
 .../appsettings.json                          |  8 ++
 5 files changed, 153 insertions(+), 1 deletion(-)
 create mode 100644 OptionsPattern.Sutdy.Experience.ConsoleApp/Options/AppOption.cs
 create mode 100644 OptionsPattern.Sutdy.Experience.ConsoleApp/Options/ReceiveMailOption.cs
 create mode 100644 OptionsPattern.Sutdy.Experience.ConsoleApp/appsettings.json

diff --git a/OptionsPattern.Sutdy.Experience.ConsoleApp/Options/AppOption.cs b/OptionsPattern.Sutdy.Experience.ConsoleApp/Options/AppOption.cs
new file mode 100644
index 0000000..29a5802
--- /dev/null
+++ b/OptionsPattern.Sutdy.Experience.ConsoleApp/Options/AppOption.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OptionsPattern.Sutdy.Experience.ConsoleApp
+{
+    public class AppOption
+    {
+        /// <summary>
+        /// 软件名
+        /// </summary>
+        public string AppName { get; set; } = "IniAppName";
+        
+        /// <summary>
+        /// 软件版本
+        /// </summary>
+        public Version AppVersion { get; set; } = new Version( "0.0.0.1");
+
+        /// <summary>
+        /// 接收邮箱配置对象
+        /// </summary>
+        public ReceiveMailOption? EMail { get; set; }
+    }
+}
diff --git a/OptionsPattern.Sutdy.Experience.ConsoleApp/Options/ReceiveMailOption.cs b/OptionsPattern.Sutdy.Experience.ConsoleApp/Options/ReceiveMailOption.cs
new file mode 100644
index 0000000..702e0f6
--- /dev/null
+++ b/OptionsPattern.Sutdy.Experience.ConsoleApp/Options/ReceiveMailOption.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OptionsPattern.Sutdy.Experience.ConsoleApp
+{
+    /// <summary>
+    /// 接收邮件配置
+    /// </summary>
+    public class ReceiveMailOption
+    {
+        /// <summary>
+        /// 接收邮箱地址
+        /// </summary>
+        public string? ReceiveAddress { get; set; }
+
+        /// <summary>
+        /// 接收人
+        /// </summary>
+        public string? Recipient{ get; set; } 
+    }
+}
diff --git a/OptionsPattern.Sutdy.Experience.ConsoleApp/OptionsPattern.Sutdy.Experience.ConsoleApp.csproj b/OptionsPattern.Sutdy.Experience.ConsoleApp/OptionsPattern.Sutdy.Experience.ConsoleApp.csproj
index 1fefe2c..2a5a3fe 100644
--- a/OptionsPattern.Sutdy.Experience.ConsoleApp/OptionsPattern.Sutdy.Experience.ConsoleApp.csproj
+++ b/OptionsPattern.Sutdy.Experience.ConsoleApp/OptionsPattern.Sutdy.Experience.ConsoleApp.csproj
@@ -9,8 +9,17 @@
 
   <ItemGroup>
     <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
     <PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <None Update="appsettings.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
 
 </Project>
diff --git a/OptionsPattern.Sutdy.Experience.ConsoleApp/Program.cs b/OptionsPattern.Sutdy.Experience.ConsoleApp/Program.cs
index a4741bc..d54ce5c 100644
--- a/OptionsPattern.Sutdy.Experience.ConsoleApp/Program.cs
+++ b/OptionsPattern.Sutdy.Experience.ConsoleApp/Program.cs
@@ -1,10 +1,95 @@
-namespace OptionsPattern.Sutdy.Experience.ConsoleApp
+using System.Text.Json;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Configuration.Memory;
+using Microsoft.Extensions.Configuration.Json;
+using Microsoft.Extensions.Options;
+
+namespace OptionsPattern.Sutdy.Experience.ConsoleApp
 {
+    /// <summary>
+    /// 6.1.3 配置源的同步
+    /// 单独一个线程,随机时间改变配置文件内容
+    /// 主线程接收的更改通知,把新配置打印到控制台窗口
+    /// </summary>
     internal class Program
     {
+        private static string jsonConfigFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"appsettings.json");
+
         static void Main(string[] args)
         {
             Console.WriteLine("============ 配置选项编程体验:6.1.3 配置源的同步 ============");
+
+            //获取配置项
+            var configuration=new ConfigurationBuilder().AddJsonFile(jsonConfigFile,false,true).Build();
+            new ServiceCollection()
+                .AddOptions()
+                .Configure<AppOption>(configuration)
+                .BuildServiceProvider()
+                .GetRequiredService<IOptionsMonitor<AppOption>>()
+                .OnChange(app => 
+                {
+                    var jsonText = JsonSerializer.Serialize(app);
+                    Console.WriteLine($"{DateTime.Now.ToString("yyyy:MM:dd HH:mm:ss FFFFFF")} 接到变更通知,新项为:");
+                    Console.WriteLine(jsonText);
+
+                });
+
+
+            //随机改变配置文件内容
+            new Thread((jsonFile) => 
+            {
+                while (true)
+                {
+                    ChangeJsonFileContent(jsonConfigFile, 5, 10);
+                }
+            })
+           .Start(jsonConfigFile);
+
+            Console.ReadLine();
+        }
+
+        /// <summary>
+        /// 随机秒数,随机改变Json配置文件配置项的值
+        /// </summary>
+        static void ChangeJsonFileContent(string jsonFileFullPath,int min=5,int max = 20)
+        {
+            if (string.IsNullOrWhiteSpace(jsonFileFullPath))
+            {
+                throw new ArgumentException($"参数{nameof(jsonFileFullPath)}不能为空!");
+            }
+
+            if (!File.Exists(jsonFileFullPath))
+            {
+                throw new FileNotFoundException($"参数{nameof(jsonFileFullPath)}指定的json配置文件不存在!");
+            }
+
+            //随机时间(秒数)
+            Random random = new Random();
+            var secondNum = random.Next(min, max);
+            Thread.Sleep(1000 * secondNum);
+
+            //读取Json配置文件内容
+            var appOption = new ConfigurationBuilder()
+                .AddJsonFile(jsonFileFullPath, false, false)
+                .Build()
+                .Get<AppOption>();
+            //改变配置项
+            appOption.AppName = Guid.NewGuid().ToString()+"_AppName";
+            appOption.AppVersion = new Version(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
+            appOption.EMail = new ReceiveMailOption()
+            {
+                ReceiveAddress = appOption.AppName + "@163.com",
+                Recipient = secondNum + "_Recipient",
+            };
+
+            //写回文件
+            var jsonText = JsonSerializer.Serialize(appOption);
+
+            File.WriteAllText(jsonFileFullPath,jsonText);
+
+            Console.WriteLine($"{DateTime.Now.ToString("yyyy:MM:dd HH:mm:ss FFFFFF")} 改变配置文件内容:");
+            Console.WriteLine(jsonText);
         }
     }
 }
\ No newline at end of file
diff --git a/OptionsPattern.Sutdy.Experience.ConsoleApp/appsettings.json b/OptionsPattern.Sutdy.Experience.ConsoleApp/appsettings.json
new file mode 100644
index 0000000..3b859c1
--- /dev/null
+++ b/OptionsPattern.Sutdy.Experience.ConsoleApp/appsettings.json
@@ -0,0 +1,8 @@
+{
+  "AppName": "JsonAppNmae",
+  "AppVersion": "0.0.0.1",
+  "EMail": {
+    "ReceiveAddress": "json@163.com",
+    "Recipient": "json"
+  }
+}