C# 默认设置。<;房地产>;始终返回默认值,而不是持久存储(XML文件)中的值

C# 默认设置。<;房地产>;始终返回默认值,而不是持久存储(XML文件)中的值,c#,.net,dll,application-settings,C#,.net,Dll,Application Settings,我最近在C#(.NET2.0)中编写了一个DLL,其中包含一个需要IP地址的类。我的一个同事修改了这个类,从“.dll.config”(XML)文件中检索IP——这显然是由他创建的“应用程序设置”文件(Settings1.Settings)自动生成的。这样做的好处是允许最终用户随意更改XML/config文件中的IP地址 不幸的是,当我从树中签出他的代码并尝试编译(或使用)这段新代码时,任何调用此DLL的应用程序都只会获得默认值,而不是文件中的值 调用配置文件的构造函数如下所示: pub

我最近在C#(.NET2.0)中编写了一个DLL,其中包含一个需要IP地址的类。我的一个同事修改了这个类,从“.dll.config”(XML)文件中检索IP——这显然是由他创建的“应用程序设置”文件(Settings1.Settings)自动生成的。这样做的好处是允许最终用户随意更改XML/config文件中的IP地址

不幸的是,当我从树中签出他的代码并尝试编译(或使用)这段新代码时,任何调用此DLL的应用程序都只会获得默认值,而不是文件中的值

调用配置文件的构造函数如下所示:

    public class form : System.Windows.Forms.Form
    {
        public form()
        {
            // This call is required by the Windows Form Designer.
            InitializeComponent();
            IP = IPAddress.Parse(Settings1.Default.IPAddress);
        }
    }
我发现一位用户说:

“旧”值(您在开发时定义的值)是硬编码的。如果franework无法访问或打开配置文件,它将使用默认值。如果在dll中使用设置,则始终会发生这种情况

  • 这是否意味着我不能在配置文件中存储DLL的外部值?(我的同事以某种方式完成了这项工作…)

  • 由于我的框架似乎无法访问或打开配置文件,我如何找出它失败的原因?或者甚至在这种情况发生时检测到

  • 戴克:那有点帮助。不幸的是,我正在将这个DLL写入一个规范,因此我实际上无法访问应用程序的配置文件。正如您在上面所注意到的,我的同事创建了一个“Settings1.settings”文件。当时我不明白这一点,但现在看来,添加“1”会将其排除在任何调用它的应用程序的设置空间之外

    我想我想弄明白的是,为什么DLL似乎没有在同一个目录中找到它旁边的配置文件。通过代码一步一步地跟踪,什么也看不到

    另外,我可以将程序集的“输出类型”从“类库”更改为“Windows应用程序”,并在DLL代码的开头添加以下行:

        [STAThread]
        public static void Main(string[] args)
        {
            System.Windows.Forms.Application.Run(new form());
        }
    

    当我运行这个程序时,它会生成一个不同的配置文件(一个“.exe.config”),我可以修改这个文件,让它从文件中提取新数据。所以我有点困惑。有什么想法吗?

    显然,您的应用程序正在尝试读取默认配置文件(可能是应用程序的配置文件)。要确保这一点,请将dll的配置文件中的键值对添加到应用程序的配置文件中,运行应用程序并查看这次是否读取了该键值对。

    我在使用app.config时看到了类似的问题。尝试从.exe而不是从Visual Studio运行应用程序,然后查看它是否按预期运行。

    我一直使用这种技术。通常,我有一个需要特定设置的库程序集,我需要通过测试项目以及主要的“可执行”程序集(无论是web项目还是Windows服务项目)来设置它们

    您是正确的,当您为任何项目创建设置文件时,它会添加一个应用程序配置文件。为任何设置输入的值都存储在两个位置——配置文件和设置基础结构创建的类的属性中。未找到配置文件时,将使用嵌入属性中的值

    以下是显示此类属性的代码段:

    下面是一个显示生成的类中ConcordanceServicesEndpointName的默认值的代码段:

        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("InternalTCP")]
    
        public string ConcordanceServicesEndpointName {
            get {
                return ((string)(this["ConcordanceServicesEndpointName"]));
            }
        }
    
    您要做的是从库程序集项目的app.config文件中复制configuration部分,并(小心地)将其合并到主程序集的适用web.config或app.config中。在运行时,这是唯一使用的配置文件

    以下是一个例子:
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
          <section name="LitigationPortal.Documents.BLL.DocumentsBLLSettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
      </configSections>
      <applicationSettings>
        <LitigationPortal.Documents.BLL.DocumentsBLLSettings>
          <setting name="ConcordanceServicesEndpointName" serializeAs="String">
            <value>InternalTCP</value>
          </setting>
        </KayeScholer.LitigationPortal.Documents.BLL.DocumentsBLLSettings>
      </applicationSettings>
    
    
    内部TCP
    


    您应该将这些部分复制到“true”配置文件中

    我在一个正在进行原型设计的应用程序中解决了这个问题。虽然Decker建议将配置文件一起进行黑客攻击,但我认为这是一种非常不方便的手动黑客攻击,作为构建周期的一部分执行。相反,我认为最干净的解决方案是让每个库解析自己的library.dll.config文件。它仍然不完美,需要一些额外的锅炉板代码,但它似乎是绕过.Net处理这些app.config文件的拜占庭方式的唯一方法。

    我想我刚刚找到了一个解释,解释了为什么我的DLL和测试应用程序无法使用它。以下是以下例外情况的结论:

    解决方法是确保应用程序和支持程序集具有相同的命名空间,或者确保合并AppName.exe.config和DllName.dll.config的内容(现在编译.dll时是的,它会生成此文件,但是如果将其复制到应用程序目录,并且不会自动合并,则会忽略此文件)

    因此,要么我必须将DLL和应用程序保持在同一名称空间中,要么我必须将DLL配置文件的内容与应用程序的配置文件合并

    (这不是违背了DLL的目的吗?我以为DLL应该是一个独立的库。)

    也许这就是为什么它对我的同事有效。生产应用程序与DLL共享相同的命名空间。(我的测试应用程序显然没有…)


    更新:我最近刚和同事坐下来,再次讨论了这个问题,似乎这个问题对他也不起作用,但他没有意识到,因为他已将初始值设置为与我们尝试使用的设备相同。因此,一开始它看起来当然可以工作,但当我们在其他地方使用稍微不同的设置部署它时,它又被破坏了。

    我已经有很长一段时间遇到了同样的问题-这很烦人

    我喜欢做你自己的公司
    IP = IPAddress.Parse(Settings1.Default.IPAddress);
    
    *IP = IPAddress.Parse(Settings1.IPAddress);
    
        string configFile = Assembly.GetExecutingAssembly().Location + ".config";
        XDocument.Load(configFile).Root.Element("appSettings")....