Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to make settings provider inside a dynamically loaded assembly available for reflection?
    primarykey
    data
    text
    <p>Following <a href="https://stackoverflow.com/questions/14651604/how-to-configure-asmx-web-service-url-from-remote-source">this question</a>, I successfully created my custom settings provider in the legacy C# app we are developing. It is referenced via the <code>SettingsProvider</code> attribute:</p> <pre><code>public sealed class MySettings : SettingsProvider { ... } [SettingsProvider(typeof(MySettings))] internal sealed partial class Settings {} </code></pre> <p>However, now I ran into another problem.</p> <p>Our client app includes an autoupdate facility, and it is implemented so that the bulk of the client - including the classes above - is built into a DLL (let's call it <em>client.dll</em> here), which is then used by an EXE. The EXE first checks for updates and downloads the latest one from the update server if needed, replacing all DLLs etc. with their newer version (including <em>client.dll</em>). In order to be able to replace DLLs at runtime, it can't link to them statically. So after the update, it loads <em>client.dll</em> and runs it like this:</p> <pre><code>Assembly assy = Assembly.LoadFile( AppDomain.CurrentDomain.BaseDirectory + "client.dll"); object frm = assy.CreateInstance("Client.Forms.MainForm"); Application.Run((Form)frm); </code></pre> <p>The unfortunate consequence of this is that the framework can't find my custom settings provider class inside the dynamically loaded assembly. I tried to use <code>LoadFrom</code> instead of <code>LoadFile</code> above but it didn't help. The only working solution I found so far is to implement a proxy class in the loader exe with the same name as the real settings provider, which is found by the framework all right. The proxy then instantiates the real settings provider from the client assembly and delegates all calls to it.</p> <p>This seems to work but I am not happy with it. Is there a way to help the framework find my class inside a dynamically loaded assembly directly?</p> <h3>Update</h3> <p>The error message I get:</p> <pre><code>System.Configuration.ConfigurationErrorsException: Failed to load provider type: Client.Properties.MySettings, Client, Version=4.0.1341.0, Culture=neutral, PublicKeyToken=null. at System.Configuration.ApplicationSettingsBase.get_Initializer() at System.Configuration.ApplicationSettingsBase.CreateSetting(PropertyInfo propInfo) at System.Configuration.ApplicationSettingsBase.EnsureInitialized() at System.Configuration.ApplicationSettingsBase.get_Properties() at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName) at System.Configuration.SettingsBase.get_Item(String propertyName) at System.Configuration.ApplicationSettingsBase.GetPropertyValue(String propertyName) at System.Configuration.ApplicationSettingsBase.get_Item(String propertyName) at Client.Properties.Settings.get_SomeConfigSetting() at ... </code></pre> <p>Via debugging and log messages I determined that the initializer method of the class is never called, so the class is never instantiated. In other words, there seems to be no hidden initialization error behind the above exception.</p> <p>One more potentially important bit: the client is currently running on .NET 2.0 and there are no plans to upgrade in the foreseeable future.</p> <h3>Update 2</h3> <p>I started to investigate the AppDomain as suggested by @jwddixon's answer. First I wanted to check whether Client.dll really ends up in a different app domain than that of the caller EXE. So I listed the assemblies in the current app domain, and saw that <em>Client</em> is in fact there. But to my surprise, I noticed that there are actually two assemblies named <em>Client</em> in the list - both the EXE and the DLL have the same assembly name, but different version (4.0.0.0 for the EXE, 4.0.1352.0 for the DLL at present). I was not fully aware of this so far, and this may be important. I will try changing the EXE assembly name next...</p> <h3>Update 3</h3> <p>...and that actually fixed the problem! Aaargh... Towards my unknown predecessors who invented this contorted scheme for who knows why, I have very unfond thoughts at this moment... but kudos to all of you guys for contributing questions and ideas which eventually lead to the solution!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload