2016-09-14 46 views
6

我試圖使用.net核心中的Options pattern強類型json配置設置。到目前爲止,所有示例都顯示了將強類型設置類注入控制器是多麼容易,但我需要在中間件類中使用它(非常類似於this question,但在嘗試這種方法後我沒有進一步前瞻)。將IOptions傳遞到.Net核心中間件類用於json配置檢索

因此,設置:

mysettings.json

{ 
    "MySettings": { 
    "Name": "Some Name from config", 
    "Description": "Some Description from config" 
    } 
} 

mysettings.cs

public class MySettings 
    { 
     public string Name { get; set; } = "Default name"; 

     public string Description { get; set; } = "Default description"; 
    } 

startup.cs

 public void ConfigureServices(IServiceCollection services) 
      { 
       services.AddMvc(); 

       // Add functionality to inject IOptions<T> 
       services.AddOptions(); 

       // Add our Config object so it can be injected 
       services.Configure<MySettings>(Configuration.GetSection("MySettings")); 
       services.AddSingleton<IMySettingsService, MySettingsService>(); 
      } 

MysettingsService.cs

 public class MysettingsService : IMysettingsService 
      { 
       private MySettings mySettings { get; set; } 

       public MysettingsService (MySettings _mySettings) 
       { 
        mySettings = _mySettings.value; 
       } 


     public string GetName() 
       { 
        return mySettings.Name; 
       } 
    } 

如何去實例MysettingsService.cs和注入IOptions<MySettings>到類的構造函數,所以我可以調用的GetName方法?

回答

14

幾點:

  • 構造函數中缺少提到的類 - MysettingsService
  • 你已經註冊IMysettingsService的實施啓動類?
  • 雖然註冊的實施,可以初始化MysettingsService,如下圖所示: services.AddSingleton<IMysettingsService, MysettingsService >(i => new MysettingsService());

遵循以下步驟:

  • 確保您已註冊的JSON文件 - mysettings。JSON - 在ConfigurationBuilder
  • 定義MySettings

    public class MySettings 
    { 
        public string Name { get; set; } 
    
        public string Description { get; set; } 
    } 
    
  • 定義MySettingsService

    public class MySettingsService : IMySettingsService 
    { 
        private readonly MySettings mySettings; 
    
        public MySettingsService (IOptions<MySettings> _mySettings) 
        { 
         mySettings = _mySettings.Value; 
        } 
    
        public string GetName() 
        { 
         return mySettings.Name; 
        } 
    } 
    
  • 在啓動

    services.Configure<MySettings>(this.Configuration.GetSection("MySettings")); 
    services.AddSingleton<IMySettingsService, MySettingsService >(); 
    

編輯 - 我包括執行你跟着

我創建了一個示例應用程序,它爲我的作品;請按照以下步驟操作:

幾個細節。 我的應用程序名是:SettingsApp

  1. 創建設置文件 - mySettings.json - 與內容
{ 
    "MySettings": { 
    "Name": "Some Name from config", 
    "Description": "Some Description from config" 
    } 
} 
  • Startup配置它
  • public Startup(IHostingEnvironment env) 
    { 
        var builder = new ConfigurationBuilder() 
         .SetBasePath(env.ContentRootPath) 
         .AddJsonFile("mySettings.json", true, reloadOnChange: true) 
         .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
         .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
         .AddEnvironmentVariables(); 
    
        if (env.IsDevelopment()) 
        { 
         // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. 
         builder.AddApplicationInsightsSettings(developerMode: true); 
        } 
        Configuration = builder.Build(); 
    } 
    

    見線:

    .AddJsonFile( 「mySettings.json」,真,reloadOnChange:真)

  • 創建MySettings對象保持設置
  • namespace SettingsApp.Initialisations 
    { 
        public class MySettings 
        { 
         public string Name { get; set; } 
    
         public string Description { get; set; } 
        } 
    } 
    

    說明:我使用命名空間SettingsApp.Initialisations來保留此文件。您可以根據您的應用程序結構選擇任何一種。

  • 創建接口IMySettingsService
  • namespace SettingsApp.Services 
    { 
        public interface IMySettingsService 
        { 
         string GetName(); 
        } 
    } 
    

    注:我使用的命名空間SettingsApp.Services此。

  • 實現接口 - IMySettingsService
  • using SettingsApp.Initialisations; 
    using Microsoft.Extensions.Options; 
    
    namespace SettingsApp.Services 
    { 
        public class MySettingsService : IMySettingsService 
        { 
         private readonly MySettings mySettings; 
    
         public MySettingsService(IOptions<MySettings> _mySettings) 
         { 
          mySettings = _mySettings.Value; 
         } 
    
         public string GetName() 
         { 
          return mySettings.Name; 
         } 
        } 
    } 
    
  • 添加的選項,讓系統知道你的實現在Startup.ConfigureServices方法
  • // This method gets called by the run time. Use this method to add services to the container. 
    public void ConfigureServices(IServiceCollection services) 
    { 
        // Options 
        services.AddOptions(); 
        services.Configure<MySettings>(this.Configuration.GetSection("MySettings")); 
        services.AddSingleton<IMySettingsService, MySettingsService>(); 
    
        // Add framework services. 
        services.AddApplicationInsightsTelemetry(Configuration); 
    
        services.AddMvc(); 
    } 
    

    請注意包括所需使用的。

    檢查如何做到這一點下面的代碼:

    // Options 
    services.AddOptions(); 
    services.Configure<MySettings>(this.Configuration.GetSection("MySettings")); 
    services.AddSingleton<IMySettingsService, MySettingsService>(); 
    
  • 使用實施(我用的是HomeController進行測試。)
  • public class HomeController : Controller 
    { 
        private IMySettingsService mySettingsService; 
    
        public HomeController(IMySettingsService settingsService) 
        { 
         mySettingsService = settingsService; 
        } 
    
        public IActionResult Index() 
        { 
         // Get the settings 
         var name = mySettingsService.GetName(); 
    
         return View(); 
        } 
    
    ... 
    
  • 查看結果:
  • Home controller constructor Inside the action

    +0

    感謝FO的幫助,但我已經完成了你所提到的所有步驟。我如何去使用MySettingsservice的實例來調用GetName方法?特別是,如何通過IOptions 來滿足構造函數? – iKnowNothing

    +0

    如果以上所有內容都已完成 - 並且讓配置知道mysettings.json文件(https://docs.asp.net/en/latest/fundamentals/configuration.html),我會很好奇,知道您得到了什麼作爲結果在** MySettingsService **的構造函數中?把一個調試點放在那裏,讓我們知道什麼是注入的對象? –

    +0

    謝謝。我只是意識到DI會照顧MySettingsService的構造函數,如果我只是使用它的接口。您徹底的實施幫助。 – iKnowNothing

    0

    在.NET的較新版本的上述結合方法不工作了。

    我已經創建了一個擴展方法的工作原理:

    public static void AddSettings<T>(this IServiceCollection serviceCollection, IConfiguration configuration) where T : class, new() 
        { 
         var settings = new T(); 
         configuration.Bind(typeof(T).Name, settings); 
         serviceCollection.AddSingleton(settings); 
        } 
    

    使用方法如下:

     string pathToConfigFile = "c:\\config.json"; 
         IConfiguration configuration = new ConfigurationBuilder() 
          .AddJsonFile(pathToConfigFile, optional: false, reloadOnChange: true) 
          .Build(); 
    
         var services = new ServiceCollection() 
    
         services.AddSingleton(configuration); 
    
         services.AddSettings<ConnectionSettings>(configuration); 
         services.AddSettings<LoggingSettings>(configuration); 
         services.AddSettings<AutoCreateSettings>(configuration); 
    
    相關問題