Есть ли способ инициализировать web.config в C # интерактивно? - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть проект ASP.NET MVC, над которым я сейчас работаю. Я хочу попробовать некоторый код в C # интерактиве, я нажимаю «Инициализировать интерактив с проектом». Я могу видеть переменные, классы и другие вещи в C # Interactive.

Теперь одна вещь не работает - это статическая переменная, которая определяется через web.config вызывает исключение.

Если я вставлю код (в интерактивном окне), который использует переменную web.config, не работает. В любом случае, чтобы решить эту проблему.

Я проверяю ответ от SeM и проверяю настройки приложения, в которых нет ничего enter image description here

обновление 2:

Я установил код на github с чтением настроек приложения, как указано в ответе, все еще не работал, код здесь https://github.com/anirugu/CsharpInteractiveTesting

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

C # само по себе работает как отдельное приложение с отдельным файлом конфигурации приложения. Если вы запустите это в C # интерактивно:

AppDomain.CurrentDomain.SetupInformation.ConfigurationFile

Вы увидите что-то вроде:

"<path to VS>\\CommonExtensions\\Microsoft\\ManagedLanguages\\VBCSharp\\InteractiveComponents\\InteractiveHost.exe.Config"

Итак, это используемый файл конфигурации. Конечно, он не содержит ваши переменные, поэтому код, пытающийся выполнить ConfigurationManager.AppSettings["foo"].ToString(), терпит неудачу.

Обычный способ установить файл конфигурации во время выполнения:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", fullPathToYourConfig);

Однако, это должно быть сделано до любого доступа к файлу конфигурации. Когда первый доступ сделан - файл кэшируется, и последующие изменения пути не будут иметь никакого эффекта. К сожалению, прежде чем дать вам доступ к выполнению команд, C # интерактивный уже работает с этим файлом.

Существуют различные хаки с отражением для сброса этого кэша. Например (дословно скопировано из здесь ):

public static void ChangeConfigTo(string path)
{
    AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);
    typeof(ConfigurationManager)
        .GetField("s_initState", BindingFlags.NonPublic |
            BindingFlags.Static)
        .SetValue(null, 0);

    typeof(ConfigurationManager)
        .GetField("s_configSystem", BindingFlags.NonPublic |
            BindingFlags.Static)
        .SetValue(null, null);

    typeof(ConfigurationManager)
        .Assembly.GetTypes()
        .Where(x => x.FullName ==
            "System.Configuration.ClientConfigPaths")
        .First()
        .GetField("s_current", BindingFlags.NonPublic |
            BindingFlags.Static)
        .SetValue(null, null);
}

Имея все это в виду, если вы поместите эту функцию в класс Program в своем примере на github и сделаете это в C # интерактивно:

Program.ChangeConfigTo(Path.GetFullPath("app.config"));

Ваш код будет работать так, как вы ожидаете. Вы можете поместить этот хак в отдельный файл скрипта (.csx) и загрузить его с "#load", если необходимо.

0 голосов
/ 27 апреля 2018

Например, если вы добавите свои настройки в файл конфигурации

<appSettings>
    <add key="Test" value="Test"/>
</appSettings>

и попробуйте прочитать его по ConfigurationManager, он выдаст исключение отсутствующей ссылки или

Имя 'ConfigurationManager' не существует в текущем контексте

В интерактивном окне C # вы можете ссылаться на сборки с ключевым словом #r

#r "System.Configuration"

и тогда вы можете получить свое значение:

#r "System.Configuration"
var settings = ConfigurationManager.OpenExeConfiguration(@"bin\Debug\YourAppName.dll"); //You can use .exe files too
Console.WriteLine(settings.AppSettings.Settings["Test"].Value);

Также! Вы можете добавить все ссылки проекта, нажав правой кнопкой мыши на ваш проект -> Инициализировать Интерактив с Projcet , и VS сделает все за вас.

Обновление

Для вашего примера :

using System.Configuration;
var settings = ConfigurationManager.OpenExeConfiguration(@"D:\TestProjects\CsharpInteractiveTesting-master\CsharpInteractiveTesting-master\CsharpInteractiveTesting\bin\Debug\CsharpInteractiveTesting.exe");
Console.WriteLine(settings.AppSettings.Settings["foo"].Value);
...