0

I'm sorry to have to ask a similar question to one I've already asked and has been answered but I'm stuck here and was hoping that someone could set me on the right path again. (Original question here: Get DLL's file name of inherited class)

I have an abstract class called PluginBase.dll from which various other classes inherit. These are all compiled as different plugins for a server application. Let's look at one of these plugins, called PluginMessaging.dll which has a config file called PluginMessaging.dll.config

The method that reads the config settings is in the base class and looks something as follows:

private void ReadConfig()
{
    _runningDir = System.IO.Path.GetDirectoryName(GetType().Assembly.Location);
    _pluginFile = System.IO.Path.GetFileName(GetType().Assembly.Location);
    _configFile = _pluginFile + ".config";

    // Do stuff here that reads from _configFile
}

The line of code that assigns a value to _pluginFile is what I got from the first time I asked the question (answered by Damien_The_Unbeliever) and it works fine, as long as there is only one instance of the PluginMessaging file and its config file.

What I'm trying to do now is to make two copies of the compiled plugin, let's call them PluginMessaging_A.dll and PluginMessaging_B.dll, each with its own corresponding config file, PluginMessaging_A.dll.config and PluginMessaging_B.dll.config respectively.

The problem I'm having is that, the server application iterates through all *.dll files in its Plugins folder, instantiates each one and calls the above ReadConfig() method for each. When the function is called for PluginMessaging_A.dll everything works as expected and the value of _pluginFile is PluginMessaging_A.dll but when the ReadConfig() function for the second copy of the DLL, PluginMessaging_B.dll is called, for some reason, _pluginFile again resolves to PluginMessaging_A.dll

It would seem as if there is some table in memory that remembers the GetType().Assembly information for PluginMessaging.dll the first time it is instantiated, regardless of what physical name it has on disk and retains that for any subsequent instances of the same DLL, albeit with a different name on disk.

Community
  • 1
  • 1
Dewald Swanepoel
  • 1,651
  • 4
  • 15
  • 38

2 Answers2

1

It would seem as if there is some table in memory that remembers the GetType().Assembly information for PluginMessaging.dll the first time it is instantiated, regardless of what physical name it has on disk and retains that for any subsequent instances of the same DLL, albeit with a different name on disk.

That observation is correct. The filename is irrelevant for the assembly identity.

You think you're loading two different assemblies, but the runtime determines you're trying to load the same assembly again - and doesn't load it.

MSDN: Assembly Names:

The runtime does not consider the file name when determining an assembly's identity. The assembly identity, which consists of the assembly name, version, culture, and strong name, must be clear to the runtime.

If you do want to load the same assembly from two files, you'll need to do so in separate appdomains. See How to Load an Assembly to AppDomain with all references recursively?.

Alternatively you can alter the name, version, culture or strong name and recompile again: then you'll have two different versions.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • Great answer, thanks. I'm afraid though that I'm not quite sure how to apply the solution provided in the link to my scenario but at least now I have something I can study. Recompiling with a new name/version/culture isn't exactly feasible as I'm hoping to get to a point where any number of copies of a plugin can be made, and given unique file names, so that the behaviour of each is defined by its config file. – Dewald Swanepoel Nov 23 '15 at 18:01
-2

Try

_pluginFile = System.IO.Path.GetFileName(GetType().Assembly.GetExecutingAssembly().Location);
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
AGdev
  • 616
  • 8
  • 12
  • "Try this" is not an answer. Explain your solution, so it is clear that you understood OP's problem, and explain your code, so that we can verify that the code you pasted solves that problem. In this case, it doesn't: it'll return the executing assembly's path for whichever type you call it. – CodeCaster Nov 23 '15 at 11:11