代码之家  ›  专栏  ›  技术社区  ›  Anirudha Gupta

有没有办法初始化web。在C#interactive中配置?

  •  2
  • Anirudha Gupta  · 技术社区  · 6 年前

    我有一个ASP。NET MVC项目,我目前正在进行。我想在C#interactive中尝试一些代码,我单击“Initialize interactive with project”我可以在c#interactive中看到变量、类和其他东西。

    现在有一件事被打破了,那就是通过web定义的静态变量。配置正在引发异常。

    如果我粘贴使用web的代码(在交互式窗口中)。配置变量不工作。无论如何都要修复此问题。

    我通过SeM检查答案,我检查应用程序设置,它没有任何内容 enter image description here

    更新2:

    我在github上设置了代码,并按照答案中给出的方式读取appsettings,但仍然不起作用,代码在这里 https://github.com/anirugu/CsharpInteractiveTesting

    2 回复  |  直到 6 年前
        1
  •  5
  •   Evk    6 年前

    C#interactive本身作为单独的应用程序运行,并具有单独的应用程序配置文件。如果在C#interactive中运行此操作:

    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#interactive已经可以使用该文件。

    有各种各样的黑客通过反射来重置缓存。例如(逐字复制自 here ):

    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#interactive中执行此操作:

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

    您的代码将按预期工作。你可以把这个黑客放在单独的脚本中( .csx )如有必要,使用“#load”(加载)进行文件和加载。

        2
  •  2
  •   SᴇM    6 年前

    例如,如果将设置添加到配置文件中

    <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);
    

    而且您可以通过以下方式添加项目的所有引用: 右键单击项目->初始化与项目集的交互 VS将为您提供一切。

    使现代化

    对于 your example :

    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);