CreateInstanceAndUnwrap fails to load assembly
Asked Answered
A

1

6

I am trying to load an assembly A in a new AppDomain in my console application with same base directory and RelativePath as the default domain.

When I create a type from A using CreateInstanceFrom it succeeds but when I use CreateInstanceAndUnwrap it fails to find assembly file with FileLoadException. Keep in mind that assembly A.MyType calls a method from assembly B.Typeb in it's constructor. Both assemblies files are present at the same path in parent folder of executing assembly (..\Mytypes)

_domain = AppDomain.CreateDomain("MyDomain" + Guid.NewGuid(), null, AppDomain.CurrentDomain.SetupInformation);
var mytype = _domain.CreateInstanceAndUnwrap(pathtoassembly, typename);

Here is the error message:

Could not load file or assembly '..\Mytypes\A.dll' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)`

Anchylose answered 8/4, 2013 at 15:28 Comment(2)
CreateInstanceAndUnwrap takes the assembly name as the first parameter, not the path to the assembly. Also, the path ..\MyTypes is outside the application base directory and so it is not used when probing for assemblies.Saffian
You will have to document your question with the trace that you get from Fuslogvw.exeMaker
S
16

AppDomain.CreateInstanceAndUnwrap will load the assembly in the Load context while the AppDomain.CreateInstanceFromAndUnwrap will load the assembly in the LoadFrom context.

The reason it work with the CreateInstanceFromAndUnwrap method is that the LoadFrom context will try to resolve assemblies in the Mytypes folder. The Load context will not. It will try to resolve only from the GAC, the BaseDirectory and the RelativeSearchPath of the AppDomain.

Some of the options you have are:

  1. Use the LoadFrom context (by using the CreateInstanceFromXXX methods).
  2. Add the Mytypes folder to the AppDomainSetup.PrivateBinPath used to create the AppDomain. This way the Load context will be able to resolve the assebmlies located there.
  3. Subscribe to the AppDomain.AssemblyResolve event and resolve the assemblies yourself by looking for them and loading them from the Mytypes folder.
  4. Deploy all your assemblies in the base directory of your application.

I suggest the 2 option which will allow the folder structure you want plus the Load context which generally the preffered choice.

Silage answered 9/4, 2013 at 9:14 Comment(2)
I tried #2 with CreateInstanceAndUnwrap and it still kept looking in the base directory of executing assembly as given in the log. However when I tried it with CreateInstanceFromAndUnwrap it worked just fine. Still there is a confusion created by the assemblyName parameter which in-fact refers to the file name and it's path not the assembly name.Anchylose
If the directories specified for PrivateBinPath are not under ApplicationBase, they are ignored.Gagne

© 2022 - 2024 — McMap. All rights reserved.