Question

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.

Was it helpful?

Solution

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);
                        };

OTHER TIPS

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?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top