www.tengbo9887.com,腾博游戏|官网
互联网
您所在的位置是:www.tengbo9887.com > 互联网 >
互联网
您所在的位置是:www.tengbo9887.com > 互联网 >

互联网

[.NET Core的Options情势] 针对Options对象的依赖性注入[上篇]

发布时间:2019-12-25 00:11    浏览次数 :

ContactInfo.Equals(other.ContactInfo);

解决问题

 

  带着上面的两个问题,我们首先来添加一个配置文件 siteconfig.json

  

  {

    "SiteBaseConfig": {

      //文件上传路径

      "FileUpPath": "/upload/",

      //是否启用单用户登录

      "IsSingleLogin": "True",

      //允许上传的文件格式

      "AttachExtension": "gif,jpg,jpeg,png,bmp,rar,zip,doc,docx,xls,xlsx,ppt,pptx,txt,flv,apk,mp4,mpg,ts,mpeg,mp3,bak,pdf",

      //图片上传最大值KB

      "AttachImagesize": 12400

    }
  }

 

我们在 读取文件配置(一)中的配置类 ApplicationConfiguration

 

 1 public class ApplicationConfiguration
 2     {
 3         #region 属性成员
 4 
 5         /// <summary>
 6         /// 文件上传路径
 7         /// </summary>
 8         public string FileUpPath { get; set; }
 9         /// <summary>
10         /// 是否启用单用户登录
11         /// </summary>
12         public bool IsSingleLogin { get; set; }
13         /// <summary>
14         /// 允许上传的文件格式
15         /// </summary>
16         public string AttachExtension { get; set; }
17         /// <summary>
18         /// 图片上传最大值KB
19         /// </summary>
20         public int AttachImagesize { get; set; }
21         #endregion
22     }

 

 

  在 project.json 的 buildOptions 添加 "copyToOutput": "siteconfig.json",让该文件在编译的时候自动拷贝到输出目录下(默认为bin目录):

 

  图片 1

 

修改  读取文件配置(一) 的领域层 AppConfigurtaionServices

 

  public class AppConfigurtaionServices
  {

    

    public T GetAppSettings<T>(string key)where T:class,new()

    {

      IConfiguration config = new ConfigurationBuilder()

                  .Add(new JsonConfigurationSource { Path= "siteconfig.json", ReloadOnChange=true })

                  .Build();

 

      var appconfig= new ServiceCollection()

              .AddOptions()

              .Configure<T>(config.GetSection(key))

              .BuildServiceProvider()

              .GetService<IOptions<T>>()

              .Value;

 

      return appconfig;

    }

 

  }  

  

  说明:我们首先创建了一个ConfigurationBuilder对象,并在它上面注册了一个JsonConfigurationSource。在创建这个JsonConfigurationSource对象的时候,除了指定配置文件(“siteconfig.json”)的路径之外,我们还将它的 ReloadOnChange 属性设置为True。这个ReloadOnChange属性的含义就是当原始配置文件的内容发生改变的时候是否需要重新加载配置。

 

  这时候我们会发现 Configure<T>(config.GetSection(key)) 报错:图片 2

 

 

  我查看了我们之前在Startup中的 services.Configure<T>() 发现,这个里面的参数是有两个重载的 一个是 IConfiguration 一个是 System.Action<T>,那么为什么这里重载不出来了呢?

 

   十分不解,最后发现是少了扩展类 Microsoft.Extensions.Options.ConfigurationExtensions

 

  我们通过 NuGet 添加这个 Install-Package Microsoft.Extensions.Options.ConfigurationExtensions  问题得到解决,在此感谢 @Artech

 

  我们来测试一下:

  图片 3

  图片 4

 

 

  OK,这样,我们在文章开始提出的两个问题就都得到了解决!

 

 

 

 

 

希望跟大家一起学习Asp.net Core 

刚开始接触,水平有限,很多东西都是自己的理解和翻阅网上大神的资料,如果有不对的地方和不理解的地方,希望大家指正!

虽然Asp.net Core 现在很火热,但是网上的很多资料都是前篇一律的复制,所以有很多问题我也暂时没有解决,希望大家能共同帮助一下!

 

原创文章 转载请尊重劳动成果 http://yuangang.cnblogs.com

 

Microsoft.Extensions.Configuration.Binder

//字段

三、DbConfigurationSource

如下所示的是DbConfigurationSource的定义,它的构造函数接受两个参数,第一个参数类型为Action<DbContextOptionsBuilder>的委托对象,我们用它来对创建DbContext采用的DbContextOptions进行设置,另一个可选的参数用来指定一些需要自动初始化的配置项。DbConfigurationSource在重写的Build方法中利用这两个对象创建一个DbConfigurationProvider对象。

   1: public class DbConfigurationSource : IConfigurationSource

   2: {

   3:     private Action<DbContextOptionsBuilder> _setup;

   4:     private IDictionary<string, string> _initialSettings;

   5:  

   6:     public DbConfigurationSource(Action<DbContextOptionsBuilder> setup, IDictionary<string, string> initialSettings = null)

   7:     {

   8:         _setup               = setup;

   9:         _initialSettings     = initialSettings;

  10:     }

  11:     public IConfigurationProvider Build(IConfigurationBuilder builder)

  12:     {

  13:         return new DbConfigurationProvider(_setup, _initialSettings);

  14:     }

  15: }

"emailAddress": "foo@outlook.com",

 

然后一个扩展方法:

public person(string name,int age,char gender)

四、DbConfigurationProvider

DbConfigurationProvider派生于抽象类ConfigurationProvider。在重写的Load方法中,它会根据提供的Action<DbContextOptionsBuilder>创建ApplicationSettingsContext对象,并利用后者从数据库中读取配置数据并转换成字典对象并赋值给代表配置字典的Data属性。如果数据表中没有数据,该方法还会利用这个DbContext对象将提供的初始化配置添加到数据库中。

   1: public class DbConfigurationProvider: ConfigurationProvider

   2: {

   3:     private IDictionary<string, string>         _initialSettings;

   4:     private Action<DbContextOptionsBuilder>     _setup;

   5:  

   6:     public DbConfigurationProvider(Action<DbContextOptionsBuilder> setup, IDictionary<string, string> initialSettings)

   7:     {

   8:         _setup               = setup;

   9:         _initialSettings     = initialSettings?? new Dictionary<string, string>() ;

  10:     }

  11:  

  12:     public override void Load()

  13:     {

  14:         DbContextOptionsBuilder<ApplicationSettingsContext> builder = new DbContextOptionsBuilder<ApplicationSettingsContext>();

  15:         _setup(builder);

  16:         using (ApplicationSettingsContext dbContext = new ApplicationSettingsContext(builder.Options))

  17:         {

  18:             dbContext.Database.EnsureCreated();

  19:             this.Data = dbContext.Settings.Any()? dbContext.Settings.ToDictionary(it => it.Key, it => it.Value, StringComparer.OrdinalIgnoreCase): this.Initialize(dbContext);

  20:         }

  21:     }

  22:  

  23:     private IDictionary<string, string> Initialize(ApplicationSettingsContext dbContext)

  24:     {

  25:         foreach (var item in _initialSettings)

  26:         {

  27:             dbContext.Settings.Add(new ApplicationSetting(item.Key, item.Value));

  28:         }

  29:         return _initialSettings.ToDictionary(it => it.Key, it => it.Value, StringComparer.OrdinalIgnoreCase);

  30:     }

  31: }

}

简介

 

  我们在 读取配置文件(一) appsettings.json 中介绍了,如何读取appsettings.json.

  但随之产生了问题:我们使用的是在 Startup.cs 中(如下图)来实现配置读取,有两个问题 ① 我们如果定义N种配置,是否要再这里添加N条这样的配置 ; ② 如果我们的配置不想写在appsettings.json中呢 

  图片 5

  

 

 

 

Microsoft.Extensions.Options.ConfigurationExtensions

  this.Name=name;this.Age=age;this.Gender=gender;

我们在《聊聊默认支持的各种配置源》和《深入了解三种针对文件(JSON、XML与INI)的配置源》对配置模型中默认提供的各种ConfigurationSource进行了深入详尽的介绍,如果它们依然不能满足项目中的配置需求,我们可以还可以通过自定义ConfigurationProvider来支持我们希望的配置来源。就配置数据的持久化方式来说,将培植存储在数据库中应该是一种非常常见的方式,接下来我们就是创建一个针对数据库的ConfigurationSource,它采用最新的Entity Framework Core来完成数据库的存取操作。篇幅所限,我们不可能对Entity Framework Core相关的编程作单独介绍,如果读者朋友们对此不太熟悉,可以查阅Entity Framework Core在线文档。 [ 本文已经同步到《ASP.NET Core框架揭秘》之中]

Age == other.Age &&

目录索引 

 

【无私分享:ASP.NET CORE 项目实战】目录索引

 

  var mySettings = new MySettings("foo"); 
  services.ConfigurePOCO(Configuration.GetSection("MySettings"), mySettings);
  //或者
  services.ConfigurePOCO(Configuration.GetSection("MySettings"), () => new MySettings("foo"));

1代表当前类的对象 2 显示的调用当前类的构造函数

一、在应用中使用自定义的DbConfigurationSource

我们将这个自定义ConfigurationSource命名为DbConfigurationSource。在正式对它的实现展开介绍之前,我们先来看看它在项目中的应用。我们创建一个控制台程序来演示对这个DbConfigurationSource应用。我们将配置保存在SQL Server数据库中的某个数据表中,并采用Entity Framework Core来读取配置,所以我们需要添加针对“ Microsoft.EntityFrameworkCore”和“Microsoft.EntityFrameworkCore.SqlServer”这两个NuGet包的依赖。除此之外,我们的实例程序会采用Options模式将读取的配置绑定为了一个Options对象,所以我们添加了针对NuGet包“Microsoft.Extensions.DependencyInjection”和“Microsoft.Extensions.Options.ConfigurationExtensions”的依赖。

   1: {

   2:   ...

   3:   "buildOptions": {

   4:     ...

   5:     "copyToOutput": "connectionString.json"

   6:   },

   7:  

   8:   "dependencies": {

   9:     ...

  10:     "Microsoft.Extensions.Options.ConfigurationExtensions"    : "1.0.0",

  11:     "Microsoft.Extensions.DependencyInjection"                : "1.0.0",

  12:     "Microsoft.Extensions.Configuration.Json"                 : "1.0.0",

  13:     "Microsoft.EntityFrameworkCore.SqlServer"                 : "1.0.0",

  14:     "Microsoft.EntityFrameworkCore"                           : "1.0.0"

  15:   } 

  16: }

我们将链接字符串作为配置定义在一个名为“connectionString.json”的JSON文件中,所以我们添加了针对NuGet包“Microsoft.Extensions.Configuration.Json”的依赖。链接字符串采用如下的形式定义在这个JSON文件中的定义,我们修改了“buildOptions/copyToOutput”配置项使这个文件可以在编译的时候可以自动拷贝到输出目录下。

   1: {

   2:   "connectionStrings": {

   3:     "defaultDb":  "Server = ... ; Database=...; Uid = ...; Pwd = ..."

   4:   }

   5: }

我们编写了如下的程序来演示针对自定义ConfigurationSource(DbConfigurationSource)的应用。我们首先创建了一个ConfigurationBuilder对象,并注册了一个指向“connectionString.json”文件的JsonConfigurationSource。针对DbConfigurationSource的注册体现在扩展方法AddDatabase上,这个方法接收两个参数,它们分别代表链接字符串的名称和初始的配置数据。前者正式“connectionString.json”设置的连接字符串名称“defaultDb”,后者是一个字典对象,它提供的原始配置正好可以构成一个Profile对象。在利用ConfigurationBuilder创建出相应的Configuration对象之后,我们采用标准的Options编程模式读取配置将将其绑定为一个Profile对象。

   1: var initialSettings = new Dictionary<string, string>

   2: {

   3:     ["Gender"]             = "Male",

   4:     ["Age"]                 = "18",

   5:     ["ContactInfo:EmailAddress"]     = "foobar@outlook.com",

   6:     ["ContactInfo:PhoneNo"]         = "123456789"

   7: };

   8:  

   9: IConfiguration config = new ConfigurationBuilder()

  10:     .AddJsonFile("connectionString.json")

  11:     .AddDatabase("DefaultDb", initialSettings)

  12:     .Build();

  13:  

  14: Profile profile = new ServiceCollection()

  15:     .AddOptions()

  16:     .Configure<Profile>(config)

  17:     .BuildServiceProvider()

  18:     .GetService<IOptions<Profile>>()

  19:     .Value;

  20:  

  21: Debug.Assert(profile.Gender == Gender.Male);

  22: Debug.Assert(profile.Age == 18);

  23: Debug.Assert(profile.ContactInfo.EmailAddress == "foobar@outlook.com");

  24: Debug.Assert(profile.ContactInfo.PhoneNo == "123456789");

  25:  

  26:  

  27: public class Profile

  28: {

  29:     public Gender         Gender { get; set; }

  30:     public int            Age { get; set; }

  31:     public ContactInfo    ContactInfo { get; set; }

  32: }

  33:  

  34: public class ContactInfo

  35: {

  36:     public string EmailAddress { get; set; }

  37:     public string PhoneNo { get; set; }

  38: }

  39:  

  40: public enum Gender

  41: {

  42:     Male,

  43:     Female

  44: }

  45:  

以DI的方式使用Options

* *

 6 析构函数

目录
一、在应用中使用自定义的DbConfigurationSource
二、ApplicationSetting & ApplicationSettingsContext
三、DbConfigurationSource
四、DbConfigurationProvider
五、扩展方法AddDatabase

"contactInfo": {

注册的时候:

pubic char Gender {get;set;}

二、ApplicationSetting & ApplicationSettingsContext

如上面的代码片断所示,针对DbConfigurationSource的应用仅仅体现在我们为ConfigurationBuilder定义的扩展方法AddDatabase上,所以使用起来是非常方便的,那么这个扩展方法背后有着怎样的逻辑实现呢?DbConfigurationSource采用Entity Framework Core以Code First的方式进行数据操作,如下所示的ApplicationSetting是表示基本配置项的POCO类型,我们将配置项的Key以小写的方式存储。另一个ApplicationSettingsContext是对应的DbContext类型。

   1: [Table("ApplicationSettings")]

   2: public class ApplicationSetting

   3: {

   4:     private string key;

   5:  

   6:     [Key]

   7:     public string Key

   8:     {

   9:         get { return key; }

  10:         set { key = value.ToLowerInvariant(); }

  11:     }

  12:  

  13:     [Required]

  14:     [MaxLength(512)]

  15:     public string Value { get; set; }

  16:  

  17:     public ApplicationSetting()

  18:     {}

  19:  

  20:     public ApplicationSetting(string key, string value)

  21:     {

  22:         this.Key     = key;

  23:         this.Value   = value;

  24:     }

  25: }

  26:  

  27: public class ApplicationSettingsContext : DbContext

  28: {

  29:     public ApplicationSettingsContext(DbContextOptions options) : base(options)

  30:     {}

  31:  

  32:     public DbSet<ApplicationSetting> Settings { get; set; }

  33: }

接下来我们编写了如下的代码来演示如何采用Options模式来获取由配置文件提供的数据绑定生成的Options对象。我们调用扩展方法AddJsonFile将针对配置文件(“profile.json”)的配置源注册到创建的ConfigurationBuilder对象上,然后利用后者创建出对应的IConfigurataion对象。

除了应用 IOptions<T> .Value的方式对配置信息进行全局注册外可以应用的另一个微软给出的组件,需要依赖两个包

 //字段

五、扩展方法AddDatabase

实例演示中用来注册DbConfigurationSource的扩展方法AddDatabase具有如下的定义。该方法首先调用ConfigurationBuilder的Build方法创建出一个Configuration对象,并调用后者的扩展方法GetConnectionString根据指定的连接字符串名称得到完整的连接字符串。接下来我们调用构造函数创建一个DbConfigurationSource对象并注册到ConfigurationBuilder上。创建DbConfigurationSource对象指定的Action<DbContextOptionsBuilder>会完成针对连接字符串的设置。

   1: public static class DbConfigurationExtensions

   2: {

   3:     public static IConfigurationBuilder AddDatabase(this IConfigurationBuilder builder, string connectionStringName, IDictionary<string, string> initialSettings = null)

   4:     {

   5:         string connectionString = builder.Build().GetConnectionString(connectionStringName);

   6:         DbConfigurationSource source = new DbConfigurationSource(optionsBuilder => optionsBuilder.UseSqlServer(connectionString), initialSettings);

   7:         builder.Add(source);

   8:         return builder;

   9:     }

  10: }

.Value;

而且程序在启动时将配置单例注入到内存要好过IOptions的“懒加载”模式,而且避免对象初始化错误造成的运行时错误。

{

};

做个笔记,原文链接

{

varconfiguration = newConfigurationBuilder()

就不需要像 IOptions<T>应用之前还得注册services.AddOptions()了。(多配置行代码在团队中对不熟悉又喜欢偷懒的人来说是很烦恼的。。)

}

  • Microsoft.Extensions.Configuration.Json
  • Microsoft.Extensions.DependencyInjection
  • Microsoft.Extensions.Options.ConfigurationExtensions
public static class ServiceCollectionExtensions
{
    public static TConfig ConfigurePOCO<TConfig>(this IServiceCollection services, IConfiguration configuration, Func<TConfig> pocoProvider) where TConfig : class
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (configuration == null) throw new ArgumentNullException(nameof(configuration));
        if (pocoProvider == null) throw new ArgumentNullException(nameof(pocoProvider));

        var config = pocoProvider();
        configuration.Bind(config);
        services.AddSingleton(config);
        return config;
    }

    public static TConfig ConfigurePOCO<TConfig>(this IServiceCollection services, IConfiguration configuration, TConfig config) where TConfig : class
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (configuration == null) throw new ArgumentNullException(nameof(configuration));
        if (config == null) throw new ArgumentNullException(nameof(config));

        configuration.Bind(config);
        services.AddSingleton(config);
        return config;
    }
}

//属性

"age": "18",

private char _gender;

classProgram

如果class b 派生出 class c ; class a 派生出 class b 那么 class c会继承 class a 和class b的声明的成员;

Action<Profile> print = profile =>

public int Age {get;set;}

接下来我们需要为项目添加相关的NuGet包。由于我们采用基于JSON文件的配置,所以需要添加对应的NuGet包“Microsoft.Extensions.Configuration.Json”。由于Options模式本质上就是借助于依赖注入框架实现的一种编程模式,所以我们需要 “Microsoft.Extensions.DependencyInjection”这个NuGet包。

public class person

.SetBasePath(Directory.GetCurrentDirectory())

 

? false

作用是保护字段 对字段的取值和赋值做限制 其本质就是一个get方法 一个set方法

staticvoidMain()

//自定义函数

我们可以利用配置绑定功能将承载一组相关配置数据的IConfiguration对象转换成一个具有兼容数据结构的POCO(Plain Old CLR Object)对象,进而实现“面向对象”的配置编程,而系列介绍的“Options模式(Pattern)”则在此基础上更进了一步,它使我们可以采用依赖注入的方式直接使用绑定的这个POCO对象,我们称这个POCO对象为Options对象。除此之外,Options模式也可以直接脱离配置系统,使我们可以直接采用编程的方式来初始化Options对象。

out  关键字指定所给的参数为一个输出参数 该参数的值将返回给函数调用中使用的变量

publicenumGender

}

"phoneNo": "123"

}

"gender": "Male",

//自定义函数

{

4 构造函数调用构造函数

: Gender == other.Gender &&

{

.Configure<Profile>( "bar", configuration.GetSection( "bar"))

//第二个子类 programmer 继承父类person

PhoneNo == other.PhoneNo;

 

Console.WriteLine( $"Gender: {profile.Gender}");

}

"phoneNo": "123456789"

}

上一篇:没有了 下一篇:没有了