using Microsoft.Extensions.Configuration;

namespace OptionStudy.UnitApp
{

    /// <summary>
    /// 5.1.4 将结构化数据直接绑定为对象
    /// </summary>
    public class BindToObjectTest : IDisposable
    {

        private readonly ITestOutputHelper? testOutput;
        public BindToObjectTest(ITestOutputHelperAccessor helperAccessor)
        {
            testOutput = helperAccessor.Output;
        }

        /// <summary>
        /// 绑定配置为配置对象
        /// 需要引入 Microsoft.Extensions.Configuration.Binder 包
        /// </summary>
        [Fact]
        public void BinderFromStructuredConfig_Test()
        {
            //配置字典
            var source = new Dictionary<string, string?>()
            {
                ["AppName"] = "MemoryAppName",
                ["AppVersion"] = "2.1.2.3",
                ["EMail:ReceiveAddress"] = "memory@163.com",
                ["EMail:Recipient"] = "memory",
            };

            var config = new ConfigurationBuilder().AddInMemoryCollection(source).Build();

            //显式绑定
            {
                var appOption2 = new AppOption();
                config.Bind(appOption2);
            }

            //直接使用Get()扩展方法或Get<T>()泛型扩展方法
            //注意:上述扩展方法均定义在 Microsoft.Extensions.Configuration.Binder 库中
            //      换言之:只有引入了上面绑定库,才出现Get()扩展和Get<T>泛型扩展方法
            var appOption = config.Get<AppOption>();

            //断言
            Assert.NotNull(appOption);
            Assert.Equal("MemoryAppName", appOption.AppName);
            Assert.Equal("2.1.2.3", appOption.AppVersion);

            //子配置节:父配置对象的属性名必须和配置KEY保持一致,否则不能自动绑定。
            Assert.NotNull(appOption.EMail);
            Assert.Equal("memory@163.com", appOption.EMail.ReceiveAddress);
            Assert.Equal("memory", appOption.EMail.Recipient);

            testOutput?.WriteLine("读取结构化配置,直接绑定到配置对象类!注意子配置节:父配置对象的属性名必须和配置KEY保持一致,否则不能自动绑定。");
        }

        public void Dispose()
        {

        }
    }
}