2017-07-12 104 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

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

相关问题