访问另一个项目的设置文件

51

有没有一种方法可以从不同的项目中访问设置文件?例如,我有一个包含两个项目的解决方案(我们称它们为Proj1和Proj2)。我想从Proj1的Program.cs中访问Proj2的应用程序设置。这是可能的吗?

8个回答

61

如果您正在使用C#,答案如下:
非常简单的方法是右键单击proj2,选择设置选项卡。在顶部,您会发现设置类的访问修饰符为:internal,请将其更改为public。在proj1中添加对proj2的引用以查看proj2的Settings类。就这样。


7
好的,这绝对有道理,但是你如何在不进行编译的情况下更改这些设置呢?假设你部署了项目A,并引用了项目B的设置。你想修改来自项目B的设置,但是你只有编译到dll文件里的默认值?因为我找不到任何已部署或合并到项目A设置中的配置文件,这似乎是唯一的解释。 - mikus
我尝试过这个方法,它是有效的,但是正如@mikus所述,它有一定的限制。此外,如果您正在使用XML转换(例如SlowCheetah),即使重新编译,Proj1也无法看到来自转换的更改。 - Matt Miller
2
如果我可以投两次赞,我一定会这样做。因为我在谷歌上搜索了这个问题,并且找到了这篇帖子…… 而我显然已经点过赞了。 - Tony
@Patrick 在将类的修饰符更改为 public 后,不要忘记构建 proj2 - Daniel Bonetti
1
谢谢!这可能不是所有人都知道的,但您还需要将其他项目的设置引用为“other project name”。Properties.Settings.Default。“property name” - Kevin Moore
显示剩余2条评论

42

选项A:从其他程序集的配置文件(存储设置的地方)中解析值。

选项B:在Proj2中创建一个公共类,将其设置中必要的值作为静态属性暴露出来,然后引用该程序集到Proj1中,并从该类中使用这些值。

选项C:如果您想公开所有设置,可以将设置类的访问权限从internal修改为public

我相信还有其他方式。


4
我选择了B选项,这也是我最初想到的。谢谢! - KrisTrip
1
我尝试了选项C,但似乎没有起作用。每个项目都有单独的设置:/ - Patrick Jackson

5
我将重新发布@Kildareflare链接的内容,以备将来参考。仍然适用于VS2015,但我个人认为我更喜欢上面的“B选项”。
获取另一个项目中设置的访问权限
Visual Studio 2005的新属性编辑器是其中一个很酷的新功能。使用此属性编辑器,您可以轻松地向应用程序添加设置。但是它的实现方式存在问题。让我解释一下为什么。
通常,设置是特定于项目的。当您在项目中添加设置时,与设置文件关联的特殊自定义工具会生成一个新类,您可以使用该类来访问它。这个类的好处在于它是强类型的。但在幕后,它只是从xml文件中获取键。此生成的类被设置为“内部封闭”(internal sealed)。这会防止从任何其他程序集访问它。如果您想将编辑这些设置的位置集中在一起怎么办?
经过多次尝试,我发现了一种快速简便的方法来公开它。假设我们的解决方案中有两个项目:Engine和WinApp。每个都有设置,但我们希望它们可以从WinApp进行编辑。它看起来像这样。

Settings Before

如果你想访问引擎设置,这里有一个技巧:添加链接文件。

Add Link

链接文件将作为WinApp项目的一部分进行编译。设置类仍然是内部和密封的,但是针对的是WinApp项目而不是Engine。
这是最终结果:

Settings After

注意,我添加了一个与我的Engine项目同名的文件夹。如果您想从许多项目中添加设置,这将非常有用。
有了这个设置,您可以像从WinApp类一样从引擎类中访问设置。您可以省略引擎类中的“Engine”部分,因为它们应该在相同的命名空间中。以下是它应该看起来的样子:
namespace WinApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void AccessConfig()
        {
            Engine.Properties.Settings.Default.EngineSetting = "test";
        }
    }
}

这对我不起作用。我仍然收到“'Settings' 由于其保护级别而无法访问”的消息。 - Mugen

1
ConfigurationManager已经覆盖了这个:
string proj2Exe = @"C:\projects\proj2\bin\Debug\proj2.exe";
Configuration proj2Config = ConfigurationManager.OpenExeConfiguration(proj2Exe);
string mysetting = proj2Config .AppSettings.Settings["ThatSetting"].Value;

0

我自己没有测试过这种方法,但Eric De Carufel的小技巧可能是你需要的:

http://blog.decarufel.net/2007/10/getting-access-to-settings-in-another.html

原始链接似乎已经失效,因为他已经转移到了新的博客并删除了旧内容。

以下是原始内容:

获取另一个项目中设置的访问权限

2007年10月25日星期四

Visual Studio 2005 的一个新功能是新的属性编辑器。使用此属性编辑器,您可以轻松地向应用程序添加设置。但是它的实现方式存在问题。让我解释一下为什么。

通常,设置是特定于项目的。当您在项目中添加设置时,与设置文件关联的特殊自定义工具会生成一个新类,您可以使用该类来访问它。这个类的好处是它是强类型的。但是在幕后,它只是从 XML 文件中获取密钥。这个生成的类被设置为“internal sealed”。这防止了它被任何其他程序集访问。如果您想集中编辑这些设置,该怎么办呢?

经过多次尝试,我找到了一种快速简便的方法来实现它。假设我们的解决方案中有两个项目:一个引擎和一个 WinApp。每个项目都有设置,但我们希望它们可以从 WinApp 中进行编辑。看起来就像这样。

如果您想要访问引擎设置,这里有一个技巧:添加一个链接文件。

链接文件将作为WinApp项目的一部分进行编译。设置类仍然是内部和密封的,但是针对的是WinApp项目而不是引擎。

这是最终结果:

请注意,我添加了一个与我的引擎项目同名的文件夹。如果您想从多个项目中添加设置,这将非常有用。

有了这个设置,您可以像从引擎类一样从WinApp类中访问引擎设置。您可以省略引擎类中的“Engine”部分,因为它们应该在相同的命名空间中。以下是它应该看起来的样子:

namespace WinApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void AccessConfig()
        {
            Engine.Properties.Settings.Default.EngineSetting = "test";
        }
    }
}

1
链接已失效。 - Kuffs
找到了原来链接的内容并复制在这里(该博客现已关闭)。 - Kildareflare

0

我不得不想出另一个解决方案,因为我正在使用XML Tranforms(通过SlowCheetah)在包含设置的项目的App.config上。如果您没有这样做,我建议使用其他解决方案之一。

我在消费项目(例如Proj1)中添加了一个构建后步骤,将配置文件从Proj2的输出文件夹复制过来。这将确保配置文件应用了转换。(在我的情况下,Proj1是一个dll,所以如果您的是exe,请将DestinationFiles从“.dll.config”更改为“.exe.config”。)Proj1.csproj的片段:

<Target Name="AfterBuild">
  <Copy SourceFiles="..\Proj2\bin\$(Configuration)\Proj2.exe.config" DestinationFiles="$(TargetDir)\$(AssemblyName).dll.config" />
</Target>

然后我通过使用 ctrl+shift+拖动文件到 Proj1 中的方式,创建了一个来自 Proj2 的 Settings.settings 的链接(就像 Kildareflare 引用的博客文章中所述)。

然后我可以像这样引用 Proj1 中的设置:Proj2.Properties.Settings.Default.MySetting

注意:如果您像我一样为单元测试而这样做(Proj1 是一个测试 DLL),并且您正在使用 ReSharper 测试运行程序,请确保 配置它以在单独的 AppDomains 中运行测试


0
今天遇到了这个问题,伙计。通过将第二个项目的设置部分添加到第一个项目的app.config文件的configSections之间解决了问题。
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx">
      <section name="fullSecondProjectName" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>

然后不要忘记添加那些用户设置

<configuration>

  <configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx">
      <section name="fullSecondProjectName" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
  </configSections>

  ...

  <userSettings>
    <fullSecondProjectName>
      <setting name="LogMethodInvocation" serializeAs="String">
        <value>True</value>
      </setting>
    </fullSecondProjectName>
  </userSettings>

</configuration>

-1

由于 Settings.Designer.cs 是一个 internal 类,而且您不想干扰生成的代码文件,我建议将次要项目添加为“友元”项目。

来自:进行单元测试时使用 C# 的 "internal" 访问修饰符

将以下代码添加到 Proj2AssemblyInfo.cs

using System.Runtime.CompilerServices;

[assembly:InternalsVisibleTo("Proj1")]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接