簡體   English   中英

在 C# 類庫中使用 IConfiguration

[英]Using IConfiguration in C# Class Library

我正在使用 C# 和 Core .NET 構建一個類庫。 我正在嘗試使用config.json文件中的配置。 以下是該文件的內容:

配置文件

{
  "emailAddress":"someone@somewhere.com"
}

為了嘗試將config.json用於我的配置,我在我的project.json文件中引用了Microsoft.Framework.ConfigurationModel.Json 在我的代碼中,我有以下內容:

我的類.cs

using Microsoft.Framework.ConfigurationModel;
public class MyClass
{
  public string GetEmailAddress()
  {
//    return ConfigurationManager.AppSettings["emailAddress"];  This is the approach I had been using since .NET 2.0
    return ?;  // What goes here?
  }
}

從 .NET 2.0 開始,我一直在使用ConfigurationManager.AppSettings["emailAddress"] 但是,我現在正在嘗試通過IConfiguration學習如何以新方式進行操作。 我的問題是,這是一個類庫。 出於這個原因,我不確定配置文件是如何、在何處或何時加載的。 在傳統的 .NET 中,我只需要為 ASP.NET 項目命名一個文件 web.config,為其他項目命名一個 app.config。 現在,我不確定。 我有一個 ASP.NET MVC 6 項目和一個 XUnit 項目。 所以,我試圖弄清楚如何在這兩種情況下使用config.json

謝謝!

IMO 類庫應該與應用程序設置數據無關。 一般來說,圖書館消費者是關心這些細節的人。 是的,這並不總是正確的(例如,如果您有一個執行 RSA 加密/解密的類,您可能需要一些私有配置以允許私鑰生成/存儲),但在大多數情況下,這是正確的。

因此,一般來說,盡量將應用程序設置排除在類庫之外,並讓消費者提供此類數據。 在您的評論中,您提到了數據庫的連接字符串。 這是將數據保留在類庫之外的完美示例。 圖書館不應該關心它調用什么數據庫來讀取,只是它需要從一個數據庫中讀取。 下面的例子(如果有一些錯誤,我很抱歉,因為我是從記憶中寫出來的):

圖書館

使用連接字符串的庫類

public class LibraryClassThatNeedsConnectionString
{
    private string connectionString;

    public LibraryClassThatNeedsConnectionString(string connectionString)
    {
        this.connectionString = connectionString;
    }

    public string ReadTheDatabase(int somePrimaryKeyIdToRead)
    {
        var result = string.Empty;

        // Read your database and set result

        return result;
    }
}

應用

應用設置.json

{
  "DatabaseSettings": {
    "ConnectionString": "MySuperCoolConnectionStringWouldGoHere"
  }
}

數據庫設置.cs

public class DatabaseSettings
{
    public string ConnectionString { get; set; }
}

啟動.cs

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

    public IConfigurationRoot Configuration { get; }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // Setup logging
        // Configure app

    }

    public void ConfigureServices(IServiceCollection services)
    {
        // Configure services
        services.Configure<DatabaseSettings>(Configuration.GetSection("DatabaseSettings"));
        services.AddOptions();

        // Register our class that reads the DB into the DI framework
        services.AddTransient<IInterfaceForClass, ClassThatNeedsToReadDatabaseUsingLibrary>();
    }
}

使用庫類讀取數據庫的類

public interface IInterfaceForClass
{
    string ReadDatabaseUsingClassLibrary(int somePrimaryKeyIdToRead);
}

public class ClassThatNeedsToReadDatabaseUsingLibrary : IInterfaceForClass
{
    private DatabaseSettings dbSettings;
    private LibraryClassThatNeedsConnectionString libraryClassThatNeedsConnectionString;

    public ClassThatNeedsToReadDatabaseUsingLibrary(IOptions<DatabaseSettings> dbOptions)
    {
        this.dbSettings = dbOptions.Value;
        this.libraryClassThatNeedsConnectionString = new LibraryClassThatNeedsConnectionString(this.dbSettings.ConnectionString);
    }

    public string ReadDatabaseUsingClassLibrary(int somePrimaryKeyIdToRead)
    {
        return this.libraryClassThatNeedsConnectionString.ReadTheDatabase(somePrimaryKeyIdToRead);
    }
}

一些處理從數據庫讀取的 UI 內容的控制器類

public class SomeController : Controller
{
    private readonly classThatReadsFromDb;

    public SomeController(IInterfaceForClass classThatReadsFromDb)
    {
        this.classThatReadsFromDb = classThatReadsFromDb;
    }

    // Controller methods
}

TL;博士

盡量避免在類庫中使用應用程序設置。 相反,讓你的類庫對這些設置不可知,並讓消費者傳遞這些設置。

編輯:

我將依賴注入添加到控制器類中,以演示使用依賴注入來構建從數據庫讀取的類。 這讓 DI 系統可以解決必要的依賴關系(例如 DB 選項)。

這是一種方法(也是最好的方法)。 另一種方法是將 IOptions 注入控制器並手動更新從數據庫讀取的類並將選項傳入(不是最佳實踐,DI 是一種更好的方法)

同時支持 appSettings.json 和 appSettings.Development.json:

配置類實現:

using Microsoft.Extensions.Configuration;
using System.IO;

public static class Config
{
    private static IConfiguration configuration;

    static Config()
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appSettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile("appSettings.Development.json", optional: true, reloadOnChange: true);
        configuration = builder.Build();
    }

    public static string Get(string name)
    {
        string appSettings = configuration[name];
        return appSettings;
    }

    public static IConfigurationSection GetSection(string name)
    {
        return configuration.GetSection(name);
    }
}

配置類用法:

部分

var cosmosDb = new CosmosDbProviderConfiguration();
Config.GetSection(CosmosDbProviderConfiguration.CosmosDbProvider).Bind(cosmosDb);

鑰匙

var email = Config.Get("no-reply-email");

從未使用過它,但快速搜索將我引向這個......

var configuration = new Configuration();
configuration.AddJsonFile("config.json");
var emailAddress = configuration.Get("emailAddress");

也許你可以試試。

首先在您的.csproj文件中添加一個在構建過程中運行的目標,如果以下內容不符合您的需求,請參閱鏈接以獲取更多選項,例如發布

<Target Name="AddConfig" AfterTargets="AfterBuild">
    <Copy SourceFiles="config.json" DestinationFolder="$(OutDir)" />
</Target>

你可以像下面這樣使用它

using Microsoft.Framework.ConfigurationModel;
using Microsoft.Extensions.Configuration;
using System;

public class MyClass {
    public string GetEmailAddress() {
        //For example purpose only, try to move this to a right place like configuration manager class
        string basePath= System.AppContext.BaseDirectory;
        IConfigurationRoot configuration= new ConfigurationBuilder()
            .SetBasePath(basePath)
            .AddJsonFile("config.json")
            .Build();

        return configuration.Get("emailAddress");
    }
}

.NET 6.0+中,這是我找到的用於獲取實體框架的 connectionString 的解決方案。 找到正確的nuget 包(Microsoft.Extensions.Configuration.Json)時存在一些問題。 希望這可以為大家節省一些麻煩。

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; 
//nuget package: Microsoft.Extensions.Configuration.Json

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        var path = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
        var builder = new ConfigurationBuilder();
        builder.AddJsonFile(path);
        var root = builder.Build();
        var connectionString = root.GetSection("ConnectionStrings").GetSection("DefaultConnection").Value;
        optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
    }
}

您還可以通過右鍵單擊 .csproject -> properties-> settings-> 在右側窗口中添加新屬性來設置類庫的屬性。 確保在訪問修飾符下拉列表中選擇訪問修飾符為公共。

現在,將類庫項目引用添加到您的 .net 核心項目。

如下所述創建 appSettings.cs 類

public class AppSettings
{
    public string MyConnectionString { get; set; }
}

設置鍵值 appSettings.json

"AppSettings": {
"MyConnectionString": "yourconnectionstring",

},

現在,我們只需要從 appSettings.json 中獲取連接字符串並將屬性設置到 Startup.cs 中的類庫中,如下所示。

// This method gets called by the runtime. Use this method to add services to the container
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        // inject App setting
        var appSettingSection = Configuration.GetSection("AppSettings");
        services.Configure<AppSettings>(appSettingSection);
        var appsetting = appSettingSection.Get<AppSettings>();
        // set connection string in .csproject properties.
        classLibraryProject.Properties.Settings.Default.Properties["MyConnectionString"].DefaultValue = appsetting.MyconnectionString;


    }

筆記:

  • 確保 MyConnectionString 鍵。 在所有三個文件中它應該是相同的。
  • 確保在 ClassLibrary 項目中將 Access 修飾符設置為 Public。

我希望這可能會有所幫助。

如何使用 IConfiguration 將 AppSettings.Json 鍵值讀入 C# 控制器。

如果有人想看到它,例如 Asp.net Core .Net 5.0。 我已經完成了上述答案並為我的應用程序稍微調整了我的代碼。

如果您想了解如何在控制台應用程序中使用它,請訪問我在此鏈接上的答案,我還添加了帶有電子郵件地址的示例。


我的 AppSettings.Json 是:

{
"AppSettings": {
    "FTPLocation": "\\\\hostname\\\\c$\\\\FTPMainFolder\\\\ftpFolder\\\\Test\\",
    "FTPUri": "ftp://hostname.domainname.com/foldername/",
    "CSVFileName": "Test Load Planning.csv"  
                },
"ConnectionStrings": 
 {
 "AppDbConnString": "Server=sqlserverhostname.domainname.com;Database=DBName;Trusted_Connection=True; MultipleActiveResultSets=true"   },
 "ADSecurityGroups": { "UserSecurityGroups": "AD-DL-GROUP-NAME;AD-DL-GROUP2-NAME"},
 "Logging": 
  {
    "LogLevel": {
        "Default": "Warning"    
       }  
   }
}

我的 LoginController.cs 是:

using Microsoft.Extensions.Configuration;
public class LoginController : BaseController
{
    
    private readonly ILoginDataServices _loginDataServices;
    private readonly IConfiguration _configuration;
    public IActionResult Index()
    {
        return View();
    }


    public LoginController(ILoginDataServices loginDataServices, IConfiguration configuration)
    {
       
            _loginDataServices = loginDataServices;
            _configuration = configuration;
        
    }


    public bool CheckLogin(string userName, string password)
    {
        if (CheckIfValidEmployee(userName))
        {
            //////checking code here....
        }
        else
        {
            return false;
        }
    }

    bool CheckIfValidEmployee(string userName)
    {

        var securityGroups = _configuration.GetSection("ADSecurityGroups:UserSecurityGroups").Value.Split(';');
         Console.WriteLine(securityGroups);
       ////////Code to check user exists into security group or not using variable value
     }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM