2012-08-14 19 views
7

私は実行時にプラグインを読み込み、設定ファイルにアクセスしようとしています。構成ファイルの構成セクションは、ConfigurationElementCollection、ConfigurationElement、およびConfigurationSectionから派生したクラスにマップされます。プラグインとその設定ファイルは、 "Plugins"と呼ばれるサブフォルダ内の場所です。MEFプラグインには独自の設定ファイルがありますか?

問題は、プラグインの設定データを読み込み、それぞれのクラスに正しくデシリアライズできないようです。ここ

は、プラグインEmailPlugin.dll用のプラグインの設定の例である:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="EmailConfigurationSection" type="Foo.Plugins.EmailConfigurationSection, EmailPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true"/> 
    </configSections> 
    <EmailConfigurationSection server="192.168.0.10"> 
    <EmailSettings> 
     <add keyword="ERROR" 
        sender="[email protected]" 
        recipients="[email protected], [email protected]" 
        subject = "Error occurred" 
        body = "An error was detected" 
      /> 
    </EmailSettings> 
    </EmailConfigurationSection> 
</configuration> 

私はこのコードを使用してこれを読み込む:

private static System.Configuration.Configuration config = null; 
    public static System.Configuration.Configuration CurrentConfiguration 
    { 
     get 
     { 
      if (config == null) 
      { 
       Assembly assembly = Assembly.GetAssembly(typeof(EmailPlugin)); 
       string directory = Path.GetDirectoryName(assembly.CodeBase); 
       string filename = Path.GetFileName(assembly.CodeBase); 
       string assemblyPath = Path.Combine(directory, filename); 
       config = ConfigurationManager.OpenExeConfiguration(new Uri(assemblyPath).LocalPath); 
      } 

      return config; 
     } 
    } 

これはエラーになる:

An error occurred creating the configuration section handler for EmailConfigurationSection: Could not load file or assembly 'EmailPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. 

これを設定ファイルの先頭に追加しました:

<runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
    <probing privatePath="Plugins"/> 
    </assemblyBinding> 
</runtime> 

だから、DLLが発見されたが、私はそれを取得しようとすると、それが適切なクラスにキャストしませません。

EmailConfigurationSection defaults = CurrentConfiguration.Sections["EmailConfigurationSection"] as EmailConfigurationSection; 

それは常にnullを返します。私はこのコードを使用してXMLを取得することができますので、それが正しい場所や設定ファイルを見ていることを知っている:

var section = CurrentConfiguration.Sections["EmailConfigurationSection"]; 
string configXml = section.SectionInformation.GetRawXml(); 

しかし、私はこのコードでそれをデシリアライズしようとすると:

var serializer = new XmlSerializer(typeof(EmailConfigurationSection)); 
object result; 

EmailConfigurationSection defaults; 
using (TextReader reader = new StringReader(configXml)) 
{ 
    defaults = (EmailConfigurationSection)serializer.Deserialize(reader); 
} 

...

There was an error reflecting type 'Foo.Plugins.EmailConfigurationSection'. 

これはのInnerExceptionの内容です:私は例外を取得します3210

私はそれがクラスEmailConfigElementCollectionを参照するのですが、このクラスは、デフォルトのアクセサ持っていないため、メッセージは意味がないと仮定します。でも、と(私は他のプロジェクトで正常にこのコードを使用しました

public EmailConfigElement this[int index] 
    { 
     get 
     { 
      return (EmailConfigElement)BaseGet(index); 
     } 
     set 
     { 
      if (BaseGet(index) != null) 
      { 
       BaseRemoveAt(index); 
      } 
      BaseAdd(index, value); 
     } 
    } 

を別のDLLs/configs)、これは私がMEFでそれを使用しようとするのは初めてです。誰が問題があるか、または適切な回避策を知っていますか?

私は.NET 4.5

+0

私はあなたが単にExecutingAsseblyを使用できることをどこかで読ん:

トリックは、私は、XML構成の底にランタイムタグを移動しなければならなかったということでした。OpenExeConfigurationの場所 – Luke

+0

[MEFをエクスポートするアセンブリのカスタム構成セクション]の複製が可能です。(http://stackoverflow.com/questions/4845801/custom-configuration-sections-in-mef-exporting-assemblies) –

+0

重複していますが、http://social.msdn.microsoft.com/Forums/en-US/16df81ea-270b-47e2-bd30-877e0e32c88c/mef-plugins-with-their-own-configuration-files –

答えて

5

を使用している私は、次の変更でこれを固定: Custom configuration sections in MEF exporting assemblies:私はこの質問からこれを得た

public static System.Configuration.Configuration CurrentConfiguration 
{ 
    get 
    { 
     if (config == null) 
     { 
      // Added the next bit 
      AppDomain.CurrentDomain.AssemblyResolve += (o, args) => 
      { 
       var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); 
       return loadedAssemblies.Where(asm => asm.FullName == args.Name) 
              .FirstOrDefault(); 
      }; 

      Assembly assembly = Assembly.GetAssembly(typeof(EmailPlugin)); 
      string directory = Path.GetDirectoryName(assembly.CodeBase); 
      string filename = Path.GetFileName(assembly.CodeBase); 
      string assemblyPath = Path.Combine(directory, filename); 
      config = ConfigurationManager.OpenExeConfiguration(new Uri(assemblyPath).LocalPath); 
     } 

     return config; 
    } 
} 

。私は実際にそれを早く試してみたが、成功しなかった。

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="EmailConfigurationSection" type="Foo.Plugins.EmailConfigurationSection, EmailPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication" restartOnExternalChanges="true"/> 
    </configSections> 
    <EmailConfigurationSection server="255.255.255.1"> 
    <EmailSettings> 
     <clear /> 
     <add keyword="FOO" 
        sender="[email protected]" 
        recipients="[email protected]" 
        subject = "Foo occurred" 
        body = "Hello" 
      /> 
    </EmailSettings> 
    </EmailConfigurationSection> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <probing privatePath="Plugins"/> 
     </assemblyBinding> 
    </runtime> 
</configuration> 
+0

設定ファイルにランタイムセクションが必要なことさえありません。 –

関連する問題