app.config
またはweb.config
ファイルで次のようなことを行うことは可能ですか?
<appSettings>
<add key="MyBaseDir" value="C:\MyBase" />
<add key="Dir1" value="[MyBaseDir]\Dir1"/>
<add key="Dir2" value="[MyBaseDir]\Dir2"/>
</appSettings>
次に、単に次のように言って、コード内のDir2にアクセスします。
ConfigurationManager.AppSettings["Dir2"]
これは、app.config
全体で1つのエントリのみを変更する必要がある異なるサーバーや場所にアプリケーションをインストールするときに役立ちます。 (コード内のすべての連結を管理できることは知っていますが、この方法を好みます)。
良い質問。
あるとは思わない。簡単な方法があればよく知られていると思います。Microsoftは、展開とテストのためにさまざまな構成ファイルを展開するためのメカニズムをVisual Studio 2010で作成しています。
ただし、そうは言っています。 ConnectionStrings
セクションには、「| DataDirectory |」と呼ばれる一種のプレースホルダーがあることがわかりました。多分あなたはそこで働いているものを見ることができます...
これはmachine.config
それを示す:
<connectionStrings>
<add
name="LocalSqlServer"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
少し複雑ですが、はるかに柔軟な代替手段は、構成セクションを表すクラスを作成することです。あなたのapp.config
/web.config
ファイル、あなたはこれを持つことができます:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- This section must be the first section within the <configuration> node -->
<configSections>
<section name="DirectoryInfo" type="MyProjectNamespace.DirectoryInfoConfigSection, MyProjectAssemblyName" />
</configSections>
<DirectoryInfo>
<Directory MyBaseDir="C:\MyBase" Dir1="Dir1" Dir2="Dir2" />
</DirectoryInfo>
</configuration>
次に、.NETコード(この例ではC#を使用します)で、次のような2つのクラスを作成できます。
using System;
using System.Configuration;
namespace MyProjectNamespace {
public class DirectoryInfoConfigSection : ConfigurationSection {
[ConfigurationProperty("Directory")]
public DirectoryConfigElement Directory {
get {
return (DirectoryConfigElement)base["Directory"];
}
}
public class DirectoryConfigElement : ConfigurationElement {
[ConfigurationProperty("MyBaseDir")]
public String BaseDirectory {
get {
return (String)base["MyBaseDir"];
}
}
[ConfigurationProperty("Dir1")]
public String Directory1 {
get {
return (String)base["Dir1"];
}
}
[ConfigurationProperty("Dir2")]
public String Directory2 {
get {
return (String)base["Dir2"];
}
}
// You can make custom properties to combine your directory names.
public String Directory1Resolved {
get {
return System.IO.Path.Combine(BaseDirectory, Directory1);
}
}
}
}
最後に、プログラムコードで、app.config
変数、新しいクラスを使用して、この方法で:
DirectoryInfoConfigSection config =
(DirectoryInfoConfigSection)ConfigurationManager.GetSection("DirectoryInfo");
String dir1Path = config.Directory.Directory1Resolved; // This value will equal "C:\MyBase\Dir1"
私の拡張ライブラリを使用して達成できます: http://nuget.org/List/Packages/Expansive ソースはここから入手できます: https://github.com/anderly/Expansive
私はこの質問を見たと思った。
要するに、いや、アプリケーション構成内に変数補間はありません。
2つの選択肢があります
いくつかのオプションがあります。これは、構成ファイルを処理して、変数を正しい値に置き換えてビルド/デプロイするステップで行うことができます。
別のオプションは、これをサポートする独自の構成セクションを定義することです。たとえば、次のxmlを想像してください。
<variableAppSettings>
<variables>
<add key="@BaseDir" value="c:\Programs\Widget"/>
</variables>
<appSettings>
<add key="PathToDir" value="@BaseDir\Dir1"/>
</appSettings>
</variableAppSettings>
これで、実行時に変数の置換を処理するカスタム構成オブジェクトを使用してこれを実装します。
通常、web.configの各設定にアクセスするためのプロパティを持つ静的クラスを作成します。
public static class ConfigManager
{
public static string MyBaseDir
{
return ConfigurationManager.AppSettings["MyBaseDir"].toString();
}
public static string Dir1
{
return MyBaseDir + ConfigurationManager.AppSettings["Dir1"].toString();
}
}
通常、このクラスで必要な場合は型変換も行います。それはあなたの設定への入力されたアクセスを持つことができ、設定が変更された場合、あなたはそれらを一か所で編集することができます。
通常、設定をこのクラスに置き換えることは比較的簡単で、メンテナンス性が大幅に向上します。
内部<appSettings>
アプリケーションキーを作成できます。
<add key="KeyName" value="Keyvalue"/>
後で、次を使用してこれらの値にアクセスできます。
ConfigurationManager.AppSettings["Keyname"]
説明するシナリオのapp.config
で環境変数を使用できます
<configuration>
<appSettings>
<add key="Dir1" value="%MyBaseDir%\Dir1"/>
</appSettings>
</configuration>
次に、簡単にパスを取得できます:
var pathFromConfig = ConfigurationManager.AppSettings["Dir1"];
var expandedPath = Environment.ExpandEnvironmentVariables(pathFromConfig);
DslConfig をお勧めします。 DslConfigを使用すると、Global Configの階層構成ファイル、サーバーホストごとの構成を使用して、各サーバーホスト上のアプリケーションごとに構成できます(AppSpikeを参照)。
これが複雑な場合は、グローバル設定のVariables.varを使用できます
Varibales.varで設定するだけ
baseDir = "C:\MyBase"
Var["MyBaseDir"] = baseDir
Var["Dir1"] = baseDir + "\Dir1"
Var["Dir2"] = baseDir + "\Dir2"
そして、設定値を取得します
Configuration config = new DslConfig.BooDslConfiguration()
config.GetVariable<string>("MyBaseDir")
config.GetVariable<string>("Dir1")
config.GetVariable<string>("Dir2")
私はこの解決策を思いつきました:
すべての属性を手動で変更する必要があるため、app.xaml.csでそれを考慮する必要があるため、このソリューションにはあまり満足していません。
ここにApp.xaml.csからのコードスニペット:
string configBase = Settings.Default.ConfigurationBase;
Settings.Default.CommonOutput_Directory = Settings.Default.CommonOutput_Directory.Replace("${ConfigurationBase}", configBase);
[〜#〜] update [〜#〜]
改善が見つかりました(再びapp.xaml.csのコードスニペット):
string configBase = Settings.Default.ConfigurationBase;
foreach (SettingsProperty settingsProperty in Settings.Default.Properties)
{
if (!settingsProperty.IsReadOnly && settings.Default[settingsProperty.Name] is string)
{
Settings.Default[settingsProperty.Name] = ((string)Settings.Default[settingsProperty.Name]).Replace("${ConfigurationBase}", configBase);
}
}
これで、Type = stringおよびScope = Userを持つ設定のすべての属性に対して置換が機能します。私はこの方法が好きだと思います。
PDATE2
どうやらプロパティを実行する場合、Scope = Applicationを設定する必要はありません。
Matt Hamsmithのソリューションに従うことをお勧めします。実装するのが問題なら、これをAppSettingsクラスのバックグラウンドで実装する拡張メソッドを作成してみませんか?
何かのようなもの:
public static string GetValue(this NameValueCollection settings, string key)
{
}
メソッド内で、Linqを使用してDictionaryInfoConfigSectionを検索し、一致するキーを持つ値を返します。ただし、設定ファイルを次の行に沿って更新する必要があります。
<appSettings>
<DirectoryMappings>
<DirectoryMap key="MyBaseDir" value="C:\MyBase" />
<DirectoryMap key="Dir1" value="[MyBaseDir]\Dir1"/>
<DirectoryMap key="Dir2" value="[MyBaseDir]\Dir2"/>
</DirectoryMappings>
</appSettings>
私はパーティーに遅れることを知っています。変数構成設定の問題に対する新しい解決策があるかどうかを探していました。私が過去に使用したソリューションに触れるいくつかの答えがありますが、ほとんどは少し複雑に思えます。同じ問題に苦しんでいる人々を助けるために、古いソリューションを見て、実装をまとめると思いました。
この例では、コンソールアプリケーションで次のアプリ設定を使用しました。
_<appSettings>
<add key="EnvironmentVariableExample" value="%BaseDir%\bin"/>
<add key="StaticClassExample" value="bin"/>
<add key="InterpollationExample" value="{0}bin"/>
</appSettings>
_
Autocro autocro's answer に触れたと思います。 Visual Studioを閉じることなく、ビルドまたはデバッグするのに十分な実装を実行しています。私はこのソリューションを以前に使用しました...
警告:簡単には置き換えられない変数を使用するため、プロジェクト名または変数名に似た名前を使用してください。
SETX BaseDir "$(ProjectDir)"
'
_private void Test_Environment_Variables()
{
string BaseDir = ConfigurationManager.AppSettings["EnvironmentVariableExample"];
string ExpandedPath = Environment.ExpandEnvironmentVariables(BaseDir).Replace("\"", ""); //The function addes a " at the end of the variable
Console.WriteLine($"From within the C# Console Application {ExpandedPath}");
}
_
'
`
_private void Test_Interpollation()
{
string ConfigPath = ConfigurationManager.AppSettings["InterpollationExample"];
string SolutionPath = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"..\..\"));
string ExpandedPath = string.Format(ConfigPath, SolutionPath.ToString());
Console.WriteLine($"Using old interpollation {ExpandedPath}");
}
_
`
`
_private void Test_Static_Class()
{
Console.WriteLine($"Using a static config class {Configuration.BinPath}");
}
_
`
`
_static class Configuration
{
public static string BinPath
{
get
{
string ConfigPath = ConfigurationManager.AppSettings["StaticClassExample"];
string SolutionPath = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"..\..\"));
return SolutionPath + ConfigPath;
}
}
}
_
`
_<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="EnvironmentVariableExample" value="%BaseDir%\bin"/>
<add key="StaticClassExample" value="bin"/>
<add key="InterpollationExample" value="{0}bin"/>
</appSettings>
</configuration>
_
_using System;
using System.Configuration;
using System.IO;
namespace ConfigInterpollation
{
class Program
{
static void Main(string[] args)
{
new Console_Tests().Run_Tests();
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
}
internal class Console_Tests
{
public void Run_Tests()
{
Test_Environment_Variables();
Test_Interpollation();
Test_Static_Class();
}
private void Test_Environment_Variables()
{
string ConfigPath = ConfigurationManager.AppSettings["EnvironmentVariableExample"];
string ExpandedPath = Environment.ExpandEnvironmentVariables(ConfigPath).Replace("\"", "");
Console.WriteLine($"Using environment variables {ExpandedPath}");
}
private void Test_Interpollation()
{
string ConfigPath = ConfigurationManager.AppSettings["InterpollationExample"];
string SolutionPath = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"..\..\"));
string ExpandedPath = string.Format(ConfigPath, SolutionPath.ToString());
Console.WriteLine($"Using interpollation {ExpandedPath}");
}
private void Test_Static_Class()
{
Console.WriteLine($"Using a static config class {Configuration.BinPath}");
}
}
static class Configuration
{
public static string BinPath
{
get
{
string ConfigPath = ConfigurationManager.AppSettings["StaticClassExample"];
string SolutionPath = Path.GetFullPath(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"..\..\"));
return SolutionPath + ConfigPath;
}
}
}
}
_
構成ファイル内でappSettingsキーを定義するために変数を宣言して使用できるとは思いません。私はいつもあなたのようなコードで連結を管理してきました。
私はあなたが望むものに少し苦労していますが、オーバーライドファイルをアプリ設定に追加してから、そのオーバーライドファイルを環境ごとに設定することができます。
<appSettings file="..\OverrideSettings.config">
多くのアイテムを同様の値で設定する必要がある製品をロールアウトするには、XMLを読み取り、渡されたパラメーターに基づいて更新する小さなコンソールアプリを使用します。これらは、ユーザーに必要な情報。