Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom config section: Could not load file or assembly

Tags:

I'm having a very hard time trying to access a custom configuration section in my config file.

The config file is being read from a .dll that is loaded as a plug-in. I created the Configuration and necessary code using the Configuration Section Designer VS addin.

The namespace is 'ImportConfiguration'. The ConfigurationSection class is 'ImportWorkflows'. The assembly is ImportEPDMAddin.

The xml:

  <configSections>     <section name="importWorkflows" type="ImportConfiguration.ImportWorkflows, ImportEPDMAddin"/>   </configSections> 

Whenever I try to read in the config, I get the error:

An error occurred creating the configuration section handler for importWorkflows: Could not load file or assembly 'ImportEPDMAddin.dll' or one of its dependencies. The system cannot find the file specified.

The dll will not reside in the same directory as the executable as the software that loads the plugin places the dll and it's dependencies in it's own directory. (I can't control that.)

I edited the code for the singleton instance to the following:

string path = System.Reflection.Assembly.GetCallingAssembly().CodeBase; path = path.Replace("file:///", ""); System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(path); return configuration.GetSection(ImportWorkflowsSectionName) as ImportConfiguration.ImportWorkflows; 

I have also tried using a simple NameValueFileSectionHandler as well, but I get an exception saying that it can't load file or assembly 'System'.

I have read numerous blog posts and articles and it sounds like it is possible to read a config file in for a dll, but I just can't get it to work. Any ideas? Thanks.

like image 806
ehcanadian Avatar asked Nov 05 '09 18:11

ehcanadian


2 Answers

Unfortunately, you will need to either have the ImportEPDMAddin assembly residing in the same folder as your executable, residing in the .Net framework folder related to the .Net framework you are using (i.e., C:\Windows\Microsoft.NET\Framework\v2.0.50727), or registered in the Global Assembly Cache.

The only other option is, if you know the path to the assembly that contains the configuration handler's defining class, you can load it without a reference with something like this:

//Class global private Assembly configurationDefiningAssembly;  protected TConfig GetCustomConfig<TConfig>(string configDefiningAssemblyPath,      string configFilePath, string sectionName) where TConfig : ConfigurationSection {     AppDomain.CurrentDomain.AssemblyResolve += new          ResolveEventHandler(ConfigResolveEventHandler);     configurationDefiningAssembly = Assembly.LoadFrom(configDefiningAssemblyPath);     var exeFileMap = new ExeConfigurationFileMap();     exeFileMap.ExeConfigFilename = configFilePath;     var customConfig = ConfigurationManager.OpenMappedExeConfiguration(exeFileMap,          ConfigurationUserLevel.None);     var returnConfig = customConfig.GetSection(sectionName) as TConfig;     AppDomain.CurrentDomain.AssemblyResolve -= ConfigResolveEventHandler;     return returnConfig; }  protected Assembly ConfigResolveEventHandler(object sender, ResolveEventArgs args) {     return configurationDefiningAssembly; } 

Make sure you handle the AssemblyResolve event, as this will throw an exception without it.

like image 152
AJ. Avatar answered Oct 24 '22 03:10

AJ.


In your main applications config file, add the following (where plugins is the folder for your assembly to load from. You can use multiple paths semi-colon separated.

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

Taken from http://msdn.microsoft.com/en-us/library/823z9h8w%28v=vs.90%29.aspx

like image 42
RichardP Avatar answered Oct 24 '22 01:10

RichardP