2017-07-12 136 views
0

我已經在ASPNetCore 2017中構建了靜態AppSettings類的這個工作示例。我想知道是否有更簡單/更好的方法來實現它。我是新來的,所以我會喜歡一些專家的建議..在AspNetCore中構建/實例化靜態類的正確方法

我正在使用MiddleWare組件實例化我的Static AppSettings類,其中包含所有Json appSettings值。我這樣做是因爲我不希望Controller類必須知道如何設置要查詢的數據庫的連接字符串。我使用的是SQLClient(不是EF,因爲我所有的電話都是存儲過程)。

這是我的代碼:

appSettings.Json

{ 「的AppSettings」:{ 「WarehouseConnectionString」:「數據源= [刪除] \的SQLExpress;初始目錄=倉庫;集成安全性=真正;」 }, }

的AppSettings類

public class AppSettings 
{  
    public AppSettings() 
    { 
     // Set default values of our options. 
     WarehouseConnectionString = "WarehouseConnectionString"; 
    } 

    /// <summary> 
    /// Our Warehouse DB Connection string. 
    /// </summary> 
    public static string WarehouseConnectionString { get; set; } 
} 

我中間件類:

public class ApplicationSettingsService 
{ 
    private readonly RequestDelegate next; 

    public ApplicationSettingsService(RequestDelegate next) 
    { 
     this.next = next; 
    } 

    public async Task Invoke(HttpContext context, IOptions<AppSettings> appSettings) 
    {    
      // Create our static instance of our AppSettings class.     
      AppSettings _settings = appSettings.Value; 

      await next(context);    
    } 
} 

我Starup.cs類使用AppSetting值

public class Startup 
{ 
    public Startup(IHostingEnvironment env) 
    { 
     var builder = new ConfigurationBuilder() 
      .SetBasePath(env.ContentRootPath) 
      .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) 
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
      .AddEnvironmentVariables(); 
     Configuration = builder.Build(); 
    } 

    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) 
    { 
     //************************************************// 
     // Adds services required for using options. 
     //************************************************// 
     services.AddOptions(); 

     //**********************************************************************// 
     // Register the IConfiguration instance which MyOptions binds against the 
     // AppSettings section of the appsetting.json file only. 
     //**********************************************************************// 
     services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));   

     // Add framework services. 
     services.AddMvc(); 
    } 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
     loggerFactory.AddDebug(); 

     //******************************************************// 
     // Add our own custom Application Settings Middleware  // 
     //******************************************************//    
     app.UseMiddleware<ApplicationSettingsService>(); 

     if (env.IsDevelopment()) 
     { 
      app.UseDeveloperExceptionPage(); 
      app.UseBrowserLink(); 
     } 
     else 
     { 
      app.UseExceptionHandler("/Home/Error"); 
     } 

     app.UseStaticFiles(); 

     app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       //template: "{controller=Home}/{action=Index}/{id?}"); 
       template: "{controller=Box}/{action=Index}/{id?}"); 
     }); 
    } 
} 

我的數據庫連接類。

public static class DBConnection 
{ 
    private static string ConnectionString = AppSettings.WarehouseConnectionString; 


    public static SqlConnection GetConnection() 
    { 
     return new SqlConnection(ConnectionString); 
    } 
} 

當客戶端(控制器),使該DB類的電話,他們沒有指定連接字符串時,「倉庫」已經知道DB它應該連接到...

DHRIM5_StoredProcedureDatabaseExample.Data.Warehouse.StoredProcedures sp = new Data.Warehouse.StoredProcedures(); 

    // GET: Box 
    public ActionResult Index() 
    {    
     IList<Box> tests = sp.SPGetBoxes().ToList();    
     return View(tests); 
    } 

感謝您的幫助。

+7

靜態類不能實例化。 – Will

+0

您也可以使用SP中的EF: http://www.entityframeworktutorial.net/stored-procedure-in-entity-framework.aspx – garfbradaz

+0

檢查文檔'IOptions '和https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration如何在ASP.NET Core中使用選項/配置 – Tseng

回答

0

一般來說,您應該避免靜態類,這些類依賴於基礎結構,因爲很難對這些類進行單元測試。但是你可以在單例作用域中使用非靜態類,所以你只有一個實例。在你的情況 - 從Configuration AppSettings.cs

public class AppSettings 
{ 
    public AppSettings() 
    { 
     // Set default values of our options. 
     WarehouseConnectionString = "default_value_if_needed"; 
    } 

    public string WarehouseConnectionString { get; set; } 
} 

Startup.cs GET值並將其註冊爲單身。

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 
    services.AddMvc(); 

    var appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>(); 
    services.AddSingleton(appSettings); 
} 

然後,你可以注入該數值到構造

public class DBConnection 
{ 
    private readonly string connectionString; 

    public DBConnection(AppSettings settings) 
    { 
     this.connectionString = settings.WarehouseConnectionString; 
    } 

    public SqlConnection GetConnection() 
    { 
     return new SqlConnection(this.connectionString); 
    } 
} 

要知道在這種情況下AppSettings只在啓動應用程序讀取,因此,如果你改變appsettings.json文件,該設置將不會不適用重啓應用程序。
現在您還應該在Startup.cs - services.AddSingleton<DBConnection>();中將DbConnection註冊爲單身人士,並通過構造函數參數請求其對象。

public class StoredProcedures 
{ 
    private readonly DBConnection connection; 
    public StoredProcedures(DBConnection connection) 
    { 
     this.connection = connection; 
    } 
} 

當然,最好將接口與實現分開,並且只使用接口。

+0

從哪裏和如何調用DBConnection? – Michael

+0

我已經更新了我的答案。 –

相關問題