2015-01-10 6 views
14

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

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 в обоих этих сценариях.

Спасибо!

ответ

5

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

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

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

+4

Я видел, что тоже. Однако, кажется, действительно неэффективно загружать JSON-файл в каждый отдельный класс, который нуждается в информации о конфигурации. Например, что, если кому-то нужна строка подключения к базе данных. Должен быть какой-то способ загрузки информации о конфигурации один раз, чтобы она была доступна во всей области приложения. – user70192

+3

@ user70192 проверить этот ответ на аналогичный вопрос: http://stackoverflow.com/questions/28232364/how-can-we-store-configuration-data-in-new-asp-net-vnext/28247809#28247809 it показывает, как захватить данные только * один раз * при запуске приложения, а затем использовать инъекцию зависимостей, чтобы любой другой компонент в приложении мог получать одни и те же данные. – Eilon

-1

Не знаю, работает ли он в 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 строку в моем классе WonderContext:

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

Это не работает для меня ... Конфигурация - это нуль ... любые идеи? – chemitaxis

+0

Это работает только для asp.net 5, поэтому установите это, если вы этого еще не сделали. Вы добавили последний пакет для Microsoft.Framework.Configuration? тот, который я использовал для этого, - Microsoft.Framework.Configuration 1.0.0-beta8. Также убедитесь, что файл json находится в корневой папке (хотя это может и не изменить). Наконец, убедитесь, что вы правильно задали вызов json-файла в Configuration [""]. –

+0

Да, я добавил его ... – chemitaxis

23

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

Класс, который использует класс библиотеки для чтения к базе данных

public class ClassThatNeedsToReadDatabaseUsingLibrary 
{ 
    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); 
    } 
} 

TL; DR

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

+3

Это было очень полезно при создании нового проекта для меня. :) – Syed

+0

Я рад, что это было полезно для вас :) –

+2

Я не согласен с подходом DI в библиотеке классов. Определенно, путь. Но поскольку уровни доступа идут, моя вера статична, в результате чего зависимость вводится на уровне метода. Не конструктор. Я понимаю, что это возрастной аргумент без правильного ответа, но я склоняюсь к статической стороне. – pimbrouwers

0

Сначала в файле .csproj добавьте target that hocks in the build process, см. Ссылку для получения дополнительных сведений, если следующее не соответствует вашим потребностям, например публикация

<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"); 
    } 
} 
Смежные вопросы