Подтвердить что ты не робот

Использование IConfiguration в библиотеке классов С#

Я создаю библиотеку классов с использованием С# и Core.NET. Я пытаюсь использовать конфигурацию из файла config.json. Вот содержимое этого файла:

config.json

{
  "emailAddress":"[email protected]"
}

В попытке использовать config.json для моей конфигурации я ссылаюсь на Microsoft.Framework.ConfigurationModel.Json в моем файле project.json. В моем коде у меня есть следующее:

MyClass.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 мне просто нужно было назвать файл web.config для проектов ASP.NET и app.config для других проектов. Теперь я не уверен. У меня есть проект ASP.NET MVC 6 и проект XUnit. Итак, я пытаюсь понять, как использовать config.json в обоих этих сценариях.

Спасибо!

4b9b3361

Ответ 1

Никогда не использовал его, но быстрый поиск привел меня к этому...

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

Может быть, вы могли бы попробовать это.

Ответ 2

Библиотеки классов 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;
    }
}

заявка

appsettings.json

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

DatabaseSettings.cs

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

Startup.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);
    }
}

Некоторый класс контроллера, который обрабатывает вещи пользовательского интерфейса для чтения из БД

public class SomeController : Controller
{
    private readonly classThatReadsFromDb;

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

    // Controller methods
}

TL; DR

Старайтесь не использовать настройки приложения в библиотеке классов. Вместо этого сделайте так, чтобы ваша библиотека классов не зависела от таких настроек, и пусть потребитель передаст эти настройки.

Редактировать:

Я добавил внедрение зависимостей в класс контроллера, чтобы продемонстрировать использование внедрения зависимостей для создания класса, который читает из БД. Это позволяет системе DI разрешать необходимые зависимости (например, параметры БД).

Это один из способов сделать это (и лучший способ). Другой способ - внедрить IOptions в контроллер и вручную обновить класс, который читает из БД и передает параметры (не лучшая практика, лучше использовать DI)

Ответ 3

Это должно работать. Нужно установить пакет Microsoft.Extensions.Configuration.Json

 public static class Config
  {
    private static IConfiguration configuration;
    static Config()
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
        configuration = builder.Build();
    }

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

Ответ 4

Сначала в вашем файле .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");
    }
}

Ответ 5

Не знаю, работает ли он в библиотеке core.net, но в моем приложении mvc6 я использую его следующим образом:

public class Startup
{
    public static IConfigurationRoot Configuration;

    public Startup(IApplicationEnvironment appEnv)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(appEnv.ApplicationBasePath)
            .AddJsonFile("config.json")
            .AddEnvironmentVariables();

        Configuration = builder.Build(); 
    }
}

тогда, если мне нужно вызвать информацию в config.jason во всем приложении, я сделаю следующее: то есть в режиме контроллера:

var email = Startup.Configuration["AppSettings:SiteEmailAddress"];

sql string в моем классе WonderContext:

var connString = Startup.Configuration["AppSettings:WonderContextConnection"];