-1

I have the following deployment structure:

deployment/
    Service1.dll
    Service2.dll
    Service3.dll
    Common.dll
    Host.exe

During startup, the 3 service dlls are copied to a temporary location, and I use Assembly.LoadFrom to load the them explicitly that way. My code looks for changes in deployment and because these assemblies are loaded in their own AppDomain, I am able to shut them down, copy the new version across, and start them up again. This works great.

The problem I am having is that all 3 of these services depend on Common.dll (the main host executable does not). During startup, this common dll is also copied to the temporary location, but the host is resolving the one in deployment rather than in my temporary location.

I've tried using AppDomainSetup.PrivateBinPath and pointed it to my temporary location, but it is still resolving to the one in the deployment folder.

Is there some way I can force the CLR to look in my temporary folder first before trying to resolve it in the deployment folder (where there are other dependencies, but none that I need to "shadow", as it were).

EDIT: For clarification, if common.dll is modified, all the services are unloaded first to release the dependency on the common dll before copying and then restarting all 3.

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
  • Could try using the assembly resolve event: [Resolve Assembly References From Another Folder](http://stackoverflow.com/questions/5260404/resolve-assembly-references-from-another-folder?rq=1) – mungflesh Jun 27 '13 at 19:49
  • @mungflesh, I was under the impression that event got raised if it couldn't find the assembly... and in my case, it can - just not the one I want it to :) – Moo-Juice Jun 27 '13 at 19:52

3 Answers3

1

In the end, I solved this using the AssemblyResolve event and the current processes directory:

                    AppDomainSetup domainSetup = new AppDomainSetup()
                    {
                        ApplicationBase = _config.ShadowPath
                    };
                    AppDomain domain = AppDomain.CreateDomain(available.Description.ShortName, null, domainSetup);
                    domain.AssemblyResolve += (source, args) =>
                        {
                            int comma = args.Name.IndexOf(',');
                            string path = Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().Modules[0].FileName), args.Name.Substring(0, comma) + ".dll");
                            return Assembly.LoadFrom(path);
                        };
Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
0

It sounds like the problem is that common.dll is already loaded by the CLR by the time you make the copy. Are there static members of a type in some other assembly that reference a type in common.dll?

Keith Payne
  • 3,002
  • 16
  • 30
  • The Host executable has no dependency on it, and the "shadowing" occurs prior to any loading of the 3 service assemblies in question. Now, the `Common.dll` *does* depend on assemblies loaded by the Host.exe, but it is not loaded when the host starts (as the host as no dependency on it - doesn't even know it exists). – Moo-Juice Jun 27 '13 at 19:24
0

When you setup your AppDomain have you tried setting the ApplicationBase e.g. appDomain.SetupInformation.ApplicationBase = @"C:\ShadowCopyTest\"

Plymouth223
  • 1,905
  • 1
  • 12
  • 22
  • Have not tried this yet, but will do. How will this affect other dependencies in the deployment folder that are not shadowed, or do I have an "all or nothing" approach? – Moo-Juice Jun 28 '13 at 07:28
  • Everything in the app domain will be affected by the appbase but you can use the AppDomain.AssemblyResolve event in that scenario. – Plymouth223 Jun 29 '13 at 10:15