2016-02-26 11 views
6

Passaggio al numero IOption<T> al mio CommandBus in modo da ottenere le impostazioni dalla mia classe ServiceBusSetting. Voglio fare un test di integrazione del mio autobus. Non voglio risolverlo, usa solo new QueueCommandBus e devi passare a IOptions.Test di integrazione con IOpzioni <> in .NET Core

var services = new ServiceCollection().AddOptions(); 
     services.Configure<ServiceBusAppSettings>(Configuration.GetSection("ServiceBus")); 
     var options = services.BuildServiceProvider().GetService<IOptions<ServiceBusAppSettings>>(); 

     ////Act 
     var commandBus = new QueueCommandBus(options); 

Questo funziona bene, ma si sente il codice molto complesso per ottenere il IOptions<T> dal mio appsetting.json nel mio progetto di test.

Qualsiasi indizio se questo è l'unico modo o c'è un modo migliore?

risposta

3

Non è necessario creare lo ServiceCollection o IServiceProvider. L'interfaccia IConfiguration ha un metodo Bind(), oppure da .NET core 1.1 in poi, Get<T> che è possibile utilizzare per ottenere l'oggetto fortemente tipizzato direttamente:

var config = Configuration.GetSection("ServiceBus"); 

// .NET Core 1.0 
var options = new ServiceBusAppSettings(); 
config.Bind(options); 

// .NET Core 1.1 
var options = config.Get<ServiceBusAppSettings>(); 

Mi piace aggiungere questi metodi statici alla mia AppSettings strongly- oggetto digitato, per renderlo conveniente caricarli da JSON sia nella mia app Web sia dai test unitari.

AppSettings.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using Microsoft.Extensions.Configuration; 

namespace My.Namespace 
{ 
    public class AppSettings 
    { 
     public class ServiceBusAppSettings 
     { 
      public string Setting1; 
      public int Setting2; 
     } 

     public class ApiSettings 
     { 
      public bool FormatJson { get; set; } 
     } 

     public class MySqlSettings 
     { 
      public string User { get; set; } 
      public string Password { get; set; } 
      public string Host { get; set; } 
      public string Database { get; set; } 
      public int Port { get; set; } = 3306; 

      public string GetConnectionString() 
      { 
       return $"Server={Host};Database={Database};Port={Port};Uid={User};Pwd={Password}"; 
      } 

     } 

     public ServiceBusAppSettings ServiceBus { get; set; } = new ServiceBusAppSettings(); 
     public ApiSettings Api { get; set; } = new ApiSettings(); 
     public MySqlSettings MySql { get; set; } = new MySqlSettings(); 

     // Static load helper methods. These could also be moved to a factory class. 
     public static IConfigurationRoot GetConfiguration(string dir) 
     { 
      return GetConfiguration(dir, null); 
     } 

     public static IConfigurationRoot GetConfiguration(string dir, string environmentName) 
     { 
      if (string.IsNullOrEmpty(environmentName)) 
       environmentName = "Development"; 

      var builder = new ConfigurationBuilder() 
       .SetBasePath(dir) 
       .AddJsonFile("appsettings.json", true, true) 
       .AddJsonFile($"appsettings.{environmentName}.json", true) 
       .AddEnvironmentVariables(); 

      return builder.Build(); 
     } 

     public static AppSettings GetSettings(string dir) 
     { 
      return GetSettings(dir, null); 
     } 

     public static AppSettings GetSettings(string dir, string environmentName) 
     { 
      var config = GetConfiguration(dir, environmentName); 
      return GetSettings(config); 
     } 

     public static AppSettings GetSettings(IConfiguration config) 
     { 
      return config.Get<AppSettings>(); 
     } 
    } 
} 

ASP.NET core Startup.cs: (Ottenere le impostazioni fortemente tipizzato oggetto è spesso utile in questa fase, durante la configurazione degli altri servizi ...)

public class Startup 
{ 
    public Startup(IHostingEnvironment env) 
    { 
     Configuration = AppSettings.GetConfiguration(env.ContentRootPath, env.EnvironmentName); 
    } 

    public IConfigurationRoot Configuration { get; } 

    // This method gets called by the runtime. Use this method to add services to the container. 
    public void ConfigureServices(IServiceCollection services) 
    { 
     // Configure the service collection. 
     services.AddOptions(); 
     services.Configure<AppSettings>(Configuration); 

     // It can also be handy to get the AppSettings object here. 
     var settings = AppSettings.GetSettings(Configuration); 

     // Add framework services. 
     services.AddMvc() 
      .AddJsonOptions(options => 
      { 
       options.SerializerSettings.ContractResolver = new DefaultContractResolver(); 
       // Pretty-print JSON in Development 
       options.SerializerSettings.Formatting = settings.Api.FormatJson ? Formatting.Indented : Formatting.None; 
      }); 

     // Store DB connection info in AppSettings too... 
     var conn = settings.MySql.GetConnectionString(); 
     services.AddDbContext<MyDbContext>(opt => opt.UseMySql(conn)); 
    } 
} 

in classe di prova:

var testDir = AppContext.BaseDirectory; 
var settings = AppSettings.GetSettings(testDir, "Test"); 

//Act 
var commandBus = new QueueCommandBus(settings);