public Assembly LoadAssembly(string assemblyName) //#"D://MyAssembly.dll"
{
m_assembly = Assembly.LoadFrom(assemblyName);
return m_assembly;
}
If I put "MyAssembly.dll" both in D: and its copy in "bin" directory, the method will excute successfully. However, I delete any one of them, it will throw exception. Message like below:
Could not load file or assembly 'MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
I wanna load the assembly which exists in D:. why I need put its copy to "bin" directory at the same time?
Maybe MyAssembly.dll refers to some assembly that arent in the directory. Put all assemblies in the same directory.
Or you can handle AppDomain.CurrentDomain, AssemblyResolve event to load the needed assembly
private string asmBase ;
public void LoaddAssembly(string assemblyName)
{
asmBase = System.IO.Path.GetDirectoryName(assemblyName);
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
System.Reflection.Assembly asm = System.Reflection.Assembly.Load(System.IO.File.ReadAllBytes(assemblyName));
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
//This handler is called only when the common language runtime tries to bind to the assembly and fails.
//Retrieve the list of referenced assemblies in an array of AssemblyName.
Assembly MyAssembly, objExecutingAssemblies;
string strTempAssmbPath = "";
objExecutingAssemblies = args.RequestingAssembly;
AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();
//Loop through the array of referenced assembly names.
foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
{
//Check for the assembly names that have raised the "AssemblyResolve" event.
if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
{
//Build the path of the assembly from where it has to be loaded.
strTempAssmbPath = asmBase + "\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
break;
}
}
//Load the assembly from the specified path.
MyAssembly = Assembly.LoadFrom(strTempAssmbPath);
//Return the loaded assembly.
return MyAssembly;
}
To get any specific exceptions you could try this:
try
{
return Assembly.LoadFrom(assemblyName);
}
catch (Exception ex)
{
var reflection = ex as ReflectionTypeLoadException;
if (reflection != null)
{
foreach (var exception in reflection.LoaderExceptions)
{
// log / inspect the message
}
return null;
}
}
Related
My code uses Assembly.LoadFrom to load the main assembly, and uses reflection to inspect the types and functions in this assembly. This assembly references some other assemblies which are in different folders. When my code tries to inspect the types defined in those other assemblies, FileNotFoundException is thrown.
I can't use app.config setting to solve this problem. It all has to be done programmatically.
How do I solve this problem?
I figured out:
private static List<string> m_otherFolderPaths = new List<string> { #"C:\Projects\DllExport\trunk\Example1\HR Interface\bin\Another folder" };
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
// Ignore missing resources
if (args.Name.Contains(".resources"))
return null;
// check for assemblies already loaded
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name);
if (assembly != null)
return assembly;
// Try to load by filename - split out the filename of the full assembly name
// and append the base path of the original assembly (ie. look in the same dir)
string filename = args.Name.Split(',')[0] + ".dll".ToLower();
foreach (string folder in m_otherFolderPaths)
{
var assemblyFilePath = Path.Combine(folder, filename);
if (File.Exists(assemblyFilePath))
{
try
{
return Assembly.LoadFrom(assemblyFilePath);
}
catch
{
return null;
}
}
}
return null;
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
PrintAssembly(Assembly.LoadFrom(#"C:\Projects\DllExport\trunk\Example1\HR Interface\bin\au.com.frontedge.DllExport.Example1.DataAccess.dll"));
Console.ReadKey();
}
This question already has an answer here:
Could not load file or assembly error on GetTypes method
(1 answer)
Closed 1 year ago.
The structure of my solution is as follows:
I got 2 projects. Independent of each other at compile time (no cross references). The second one is a class library that is loaded at runtime from the first one.
That library has its own dll dependencies, which I guess is what causes the exception thrown when I'm trying to do execute code using these dlls. I supposed that these referenced dlls are probably not loaded at runtime, except from the class library dll. Therefore, I added some code to load the referenced assemblies before executing any code of the loaded assembly.
To my surprise the "problematic" dll is already included in the loaded assemblies when the following code is executed, its location is correct, but the error still occurs and I have no idea how to further troubleshoot the issue.
Any help is highly appreciated.
try
{
Assembly a = Assembly.LoadFile(Path.GetFullPath(filename));
//Try to find the type the derived plugin class
foreach (Type t in a.GetTypes())
{
if (t.IsSubclassOf(typeof(PluginBase)))
{
Console.WriteLine("Plugin class detected! {0}", t.Name);
//Get Referenced Assemblies
AssemblyName[] l = a.GetReferencedAssemblies()
//Get Loaded Assemblies
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (AssemblyName a2 in l)
{
var asm = loadedAssemblies.FirstOrDefault(a => a.FullName == a2.FullName);
if (asm == null)
{
Assembly test = null;
try
{
//First try to load using the assembly name just in case its a system dll
test = Assembly.Load(a2);
//Try to load the assemly from the plugin directory
if (test == null)
{
test = Assembly.LoadFrom(Path.Join(a.Location, a2.Name + ".dll"));
}
}
catch
{
Callbacks.Log($"Unable to load assembly {a2.Name}", LogVerbosityLevel.WARNING);
}
if (test != null)
{
Callbacks.Log($"Loaded Assembly {a2.Name}", LogVerbosityLevel.WARNING);
AppDomain.CurrentDomain.Load(test.GetName());
}
}
}
object c = Activator.CreateInstance(t, new object[] { this });
Plugins[Path.GetFileName(filename)] = c as PluginBase;
//Call Dll initializers
t.GetMethod("OnLoad").Invoke(c, new object[] { });
break;
}
}
}
catch (Exception ex)
{
Log("Error during loading of plugin " + filename, LogVerbosityLevel.INFO);
Log("Exception type " + ex.Data, LogVerbosityLevel.INFO);
}
Aight, I think I figured it out. So before the reason why I saw the referenced assemblies loaded was because I iteratively loaded them by browsing in a dll folder that contains the class library + its references. The main problem is that I am so stupid that I forgot to load them to the AppDomain calling AppDomain.CurrentDomain.Load(assemblyname). However when I did try to fix that I realized that trying to just fetch the related AssemblyName object does not work. I get the same FileNotFoundException.
What fixed the issue was to use Assembly.LoadFrom instead of Assembly.LoadFile. I read through the documentation that it states that LoadFile treats the loaded assemblies differently regardless if they are exactly the same dll file just in different location. In my case there is only a single path that I tried to load the assembly from, but I guess that LoadFile also differentiates the loaded assemblies in this case as well. However, I am still not sure why trying to use an AssemblyName coming from LoadFile crashes compared to what comes out of LoadFrom. I would expect that they would be identical...
I also added a failsafe mechanism to try and load only the desired dll files. I just expect that all dlls that will be loaded will be prepended with a text identifier. So at first the desired dll is loaded and before invoking any code, its references are loaded using the AssemblyName object or the actual path if the first fails.
Everything seems to be running nicely till now so hopefully this solves it.
foreach (string filename in Directory.GetFiles("Plugins"))
{
if (!filename.EndsWith(("dll")))
continue;
if (!Path.GetFileName(filename).StartsWith(("Test")))
continue;
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
//Load Assembly
try
{
Assembly a = Assembly.LoadFrom(Path.GetFullPath(filename));
AppDomain.CurrentDomain.Load(a.GetName());
//Try to find the type the derived plugin class
foreach (Type t in a.GetTypes())
{
if (t.IsSubclassOf(typeof(PluginBase)))
{
Console.WriteLine("Plugin class detected! {0}", t.Name);
//Load Referenced Assemblies
AssemblyName[] l = a.GetReferencedAssemblies();
loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (AssemblyName a2 in l)
{
var asm = loadedAssemblies.FirstOrDefault(a => a.FullName == a2.FullName);
if (asm == null)
{
Assembly test = null;
try
{
//First try to load using the assembly name just in case its a system dll
test = Assembly.Load(a2);
}
catch (FileNotFoundException ex)
{
try
{
Callbacks.Log($"Unable to load assembly {a2.Name}, Looking in plugin directory...", LogVerbosityLevel.WARNING);
test = Assembly.LoadFrom(Path.Join(Path.GetDirectoryName(a.Location), a2.Name + ".dll"));
} catch (Exception ex2)
{
Callbacks.Log($"Unable to load assembly {a2.Name}, Error: {ex2.Message}", LogVerbosityLevel.WARNING);
}
}
if (test != null)
{
Callbacks.Log($"Loaded Assembly {a2.Name}", LogVerbosityLevel.WARNING);
AppDomain.CurrentDomain.Load(test.GetName());
}
}
}
object c = Activator.CreateInstance(t, new object[] { this });
Plugins[Path.GetFileName(filename)] = c as PluginBase;
//Call Dll initializers
t.GetMethod("OnLoad").Invoke(c, new object[] { });
break;
}
}
}
catch (Exception ex)
{
Log("Error during loading of plugin " + filename, LogVerbosityLevel.INFO);
Log("Exception type " + ex.Data, LogVerbosityLevel.INFO);
}
}
Im trying to load assembly to my project from different folder out of root and also set a new domain for it. My goal is to load and unload during the run-time. All working fine when ddl files are in root of application, but once i put it in folder plugins im getting error file not found. I know there is a lot of topic like this but non of them cover all my needs and non of them work as excepted im afraid. It works once i loaded to current domain..
example code:
dllFileNames = Directory.GetFiles(path, "*.dll");
ICollection<Assembly> assemblies = new List<Assembly>(dllFileNames.Length);
AppDomain currentDomain = AppDomain.CurrentDomain;
Evidence asEvidence = currentDomain.Evidence;
AppDomainSetup aps = new AppDomainSetup
{
ApplicationBase = #"[root of application]",
PrivateBinPath = #"[Plugin folder]"
};
AppDomain myDomain = AppDomain.CreateDomain("Plugins",asEvidence,aps);
SimpleAssemblyLoader assemblyLoader = (SimpleAssemblyLoader)myDomain.CreateInstanceAndUnwrap(typeof(SimpleAssemblyLoader).Assembly.FullName, typeof(SimpleAssemblyLoader).FullName);
foreach (string dllFile in dllFileNames)
{
assemblyLoader.LoadFrom(dllFile);
}
var assemblyList = myDomain.GetAssemblies(); // in here getting error :( file not found for no reason.
System.IO.FileNotFoundException: 'Could not load file or assembly 'Name, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.'
public class SimpleAssemblyLoader : MarshalByRefObject
{
public void Load(string path)
{
ValidatePath(path);
Assembly.Load(path);
}
public void LoadFrom(string path)
{
ValidatePath(path);
Assembly.LoadFrom(path);
}
private void ValidatePath(string path)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
if (!System.IO.File.Exists(path))
{
throw new ArgumentException(string.Format("path \"{0}\" does not exist", path));
}
}
}
Set AppDomain.BaseDirectory to your plugins folder.
Or register AppDomain.AssemblyResolve event to resolve missing assemblies.
For .Net Core programing, take a look at AssemblyLoadContext class
I need generate typescript files from some of my C# classes after build.
I created dotnet cli tool and added post-build event
dotnet tsgenerator "$(TargetPath)"
where $(TargetPath) is macros pointing, for example, D:\Test\bin\Release\netcoreapp2.0\my.dll
Next, i tried to load assembly next way:
public static void Main(string[] args)
{
var dllPath = args[0]; // "D:\Test\bin\Release\netcoreapp2.0\my.dll"
var assembly = Assembly.LoadFile(dllPath);
var types = assembly.GetExportedTypes(); // Throws exception
}
But i got ReflectionTypeLoadException that says Could not load file or assembly for some references assemblies (for example, Microsoft.AspNetCore.Antiforgery).
How i can load assembly for .NET Core applications?
I'm found solution at github issue. Message by amits1995 and angelcalvasp.
I'm added <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> to my csproj and using this code to load assembly:
public static class AssemblyLoader
{
public static Assembly LoadFromAssemblyPath(string assemblyFullPath)
{
var fileNameWithOutExtension = Path.GetFileNameWithoutExtension(assemblyFullPath);
var fileName = Path.GetFileName(assemblyFullPath);
var directory = Path.GetDirectoryName(assemblyFullPath);
var inCompileLibraries = DependencyContext.Default.CompileLibraries.Any(l => l.Name.Equals(fileNameWithOutExtension, StringComparison.OrdinalIgnoreCase));
var inRuntimeLibraries = DependencyContext.Default.RuntimeLibraries.Any(l => l.Name.Equals(fileNameWithOutExtension, StringComparison.OrdinalIgnoreCase));
var assembly = (inCompileLibraries || inRuntimeLibraries)
? Assembly.Load(new AssemblyName(fileNameWithOutExtension))
: AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyFullPath);
if (assembly != null)
LoadReferencedAssemblies(assembly, fileName, directory);
return assembly;
}
private static void LoadReferencedAssemblies(Assembly assembly, string fileName, string directory)
{
var filesInDirectory = Directory.GetFiles(directory).Where(x => x != fileName).Select(x => Path.GetFileNameWithoutExtension(x)).ToList();
var references = assembly.GetReferencedAssemblies();
foreach (var reference in references)
{
if (filesInDirectory.Contains(reference.Name))
{
var loadFileName = reference.Name + ".dll";
var path = Path.Combine(directory, loadFileName);
var loadedAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
if (loadedAssembly != null)
LoadReferencedAssemblies(loadedAssembly, loadFileName, directory);
}
}
}
}
Usage:
public static void Main(string[] args)
{
var dllPath = args[0]; // "D:\Test\bin\Release\netcoreapp2.0\my.dll"
var assembly = AssemblyLoader.LoadFromAssemblyPath(dllPath);
var types = assembly.GetExportedTypes(); // No exceptions
}
Well you are able to load assembly but GetTypes() and GetExportedTypes() depend on the public classes within that assembly, if they have external references you get this exception.
Answer:
This means the Types of that assembly depend on other assembly which the current .NetCore does not have access at the run time because it can not connect to other dependent assemblies
Solution:
Get dependencies of the DLL assemblies and compile all of them, then load each assembly iteratively to get all ExportedTypes (i.e publicly visible Types)
Code:
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Microsoft.Extensions.DependencyModel;// add this nuget
class Program
{
static void Main(string[] args)
{
var asl = new AssemblyLoader();
var asm = asl.LoadFromAssemblyPath(#"C:\temp\Microsoft.AspNetCore.Antiforgery.dll");
try
{
var y = asm.GetExportedTypes();
Console.WriteLine(y);
}
catch (Exception e1)
{
Console.WriteLine("Got exception at first attempt of GetExportedTypes ");
Console.WriteLine("\t*********" + e1.Message + "**************");
var deped = asl.CallForDependency(asm.GetName());
try
{
Console.WriteLine("\n" + deped.ToString());
Console.WriteLine("----------All Exported Types------------");
foreach (var item in deped.ExportedTypes)
{
Console.WriteLine(item);
}
}
catch (Exception e2)
{
Console.WriteLine("Got exception at second attempt of GetExportedTypes ");
Console.WriteLine("\t*********" + e2.Message + "**************");
}
}
Console.ReadLine();
}
}
public class AssemblyLoader :AssemblyLoadContext
{
protected override Assembly Load(AssemblyName assemblyName)
{
var deps = DependencyContext.Default;
var res = deps.CompileLibraries.Where(d => d.Name.Contains(assemblyName.Name)).ToList();
var assembly = Assembly.Load(new AssemblyName(res.First().Name));
return assembly;
}
public Assembly CallForDependency(AssemblyName assemblyName)
{
return this.Load(assemblyName);
}
}
Output :
Got exception at first attempt of GetExportedTypes
*********Could not load file or assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. An operation is not legal in the current state. (Exception from HRESULT: 0x80131509)**************
Microsoft.AspNetCore.Antiforgery, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
----------All Exported Types------------
Microsoft.Extensions.DependencyInjection.AntiforgeryServiceCollectionExtensions
Microsoft.AspNetCore.Antiforgery.AntiforgeryOptions
Microsoft.AspNetCore.Antiforgery.AntiforgeryTokenSet
Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException
Microsoft.AspNetCore.Antiforgery.IAntiforgery
Microsoft.AspNetCore.Antiforgery.IAntiforgeryAdditionalDataProvider
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryFeature
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryOptionsSetup
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgerySerializationContext
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgerySerializationContextPooledObjectPolicy
Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryToken
Microsoft.AspNetCore.Antiforgery.Internal.BinaryBlob
Microsoft.AspNetCore.Antiforgery.Internal.CryptographyAlgorithms
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryAdditionalDataProvider
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenGenerator
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenStore
Microsoft.AspNetCore.Antiforgery.Internal.DefaultClaimUidExtractor
Microsoft.AspNetCore.Antiforgery.Internal.IAntiforgeryFeature
Microsoft.AspNetCore.Antiforgery.Internal.IAntiforgeryTokenGenerator
Microsoft.AspNetCore.Antiforgery.Internal.IAntiforgeryTokenSerializer
Microsoft.AspNetCore.Antiforgery.Internal.IAntiforgeryTokenStore
Microsoft.AspNetCore.Antiforgery.Internal.IClaimUidExtractor
Reference and explanation on ReflectionTypeLoadException:
Assembly.GetTypes Method ()
ReflectionTypeLoadException
The assembly contains one or more types that cannot be loaded. The
array returned by the Types property of this exception contains a Type
object for each type that was loaded and null for each type that could
not be loaded, while the LoaderExceptions property contains an
exception for each type that could not be loaded.
Remarks
The returned array includes nested types.
If the GetTypes method is called on an assembly and a type in that
assembly is dependent on a type in an assembly that has not been
loaded (for example, if it derives from a type in the second
assembly), a ReflectionTypeLoadException is thrown. For example, this
can happen if the first assembly was loaded with the
ReflectionOnlyLoad or ReflectionOnlyLoadFrom methods, and the second
assembly was not loaded. It can also happen with assemblies loaded
using the Load and LoadFile methods if the second assembly cannot be
located when the GetTypes method is called.
Note
If a type has been forwarded to another assembly, it is not included
in the returned array. For information on type forwarding, see Type
Forwarding in the Common Language Runtime.
Linked :
How to load assemblies located in a folder in .net core console app
How to dynamically load assemblies in dotnet core
Try the LoadFrom method for loading in the assembly, rather than LoadFile:
public static void Main(string[] args)
{
var dllPath = args[0]; // "D:\Test\bin\Release\netcoreapp2.0\my.dll"
var assembly = Assembly.LoadFrom(dllPath);
var types = assembly.GetExportedTypes(); // Throws exception
}
You will also need to add the same references that are in the ddl file to your current project, so that the types are defined.
I have a code like this
public static Type ToType(XmlSerializableType xmlSerializableType)
{
string func = "XmlSerialzationType.ToType";
Type type = null;
if (xmlSerializableType != null && xmlSerializableType.Name != string.Empty)
{
type = Type.GetType(xmlSerializableType.Name);
if (type == null)
{
// May be a user defined class
try
{
Assembly assembly = Assembly.Load(xmlSerializableType.AssemblyName);
type = assembly.GetType(xmlSerializableType.Name);
}
catch (Exception ex)
{
TestDebug.DebugTraceSevere(func, "Exception " + ex.ToString());
}
}
}
return type;
}
I have a base class named "leaf" and a userdefinedclass named "roundedtree"
when 'xmlSerializableType.Name' becomes userdefined class '_rounded_tree', first time i am getting value for 'assembly as _rounded_treeGOLD, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and so for 'type as {Name = "_rounded_tree" FullName = "_rounded_tree"}'. But after saving if i restart my application i cannot load value for 'assembly' getting exception 'Could not load file or assembly '_rounded_treeGOLD, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.":"_rounded_treeGOLD, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' and return type becomes null this should not happen
For baseclass "leaf" no issuses i will get xmlSerializableType.Name as " Root.Systemmodel.leaf" and 'type' becomes {Name = "leaf" FullName = "Root.Systemmodel.leaf"} assembly will be Root.Systemmodel, Version=8.0.7.0, Culture=neutral, PublicKeyToken=83bd062a94e26d58
What should i do in these circumstances
This is a bit of code which will generate assembly for userdefined class
public Type CreateType()
{
string func = "ManagedClass.CreateType";
// Create instances of AssemblyBuilder and ModuleBuilder for the new Type
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
// Create the assembly name by appending the machine name to the typename.
myAsmName.Name = this.TypeName + Environment.MachineName;
// Define assembly that can be executed but not saved
this.UserClassAssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
// Create dynamic module with symbol information
this.UserClassModuleBuilder = this.UserClassAssemblyBuilder.DefineDynamicModule("userdefinedmodule", true);
UPDATE
probably my assembly is creating for userdefined class but not saving that may be the reason i am not facing any issue first time, once i close the application i will lose that one see my code
// Define assembly that can be executed but not saved
this.UserClassAssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName,
AssemblyBuilderAccess.Run);
how to overcome this situation
UPDATE
Here my database is xml files. When i checked for base class leaf i can see the entry is <Name>Root.Systemmodel.WindowsSystem</Name><AssemblyName>Root.Systemmodel, Version=8.0.7.0, Culture=neutral, PublicKeyToken=83bd062a94e26d58</AssemblyName> in this case if restart my application no issues, but for user defined class "roundedtree" xml entry is <Name>_rounded_tree</Name> <AssemblyName>_rounded_treeGOLD, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</AssemblyName>
Here first time no issues, but if i restart my application i am getting exception
it happens because maybe the assembly you're going to load references to the another assembly that not exist in the same directory or system directory put all assembly in same folder
I,ve just copy paste my code but its clear
private string asmBase;
public Type[] GetAllTypeinAssembly(string assemblyName)
{
asmBase = System.IO.Path.GetDirectoryName(assemblyName);
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
System.Reflection.Assembly asm = System.Reflection.Assembly.Load(System.IO.File.ReadAllBytes(assemblyName));//domain.Load(bt) ;//
return asm.GetTypes();
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
//This handler is called only when the common language runtime tries to bind to the assembly and fails.
//Retrieve the list of referenced assemblies in an array of AssemblyName.
Assembly MyAssembly, objExecutingAssemblies;
string strTempAssmbPath = "";
objExecutingAssemblies = args.RequestingAssembly;
AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();
//Loop through the array of referenced assembly names.
foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
{
//Check for the assembly names that have raised the "AssemblyResolve" event.
if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
{
//Build the path of the assembly from where it has to be loaded.
strTempAssmbPath = asmBase + "\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
break;
}
}
//Load the assembly from the specified path.
MyAssembly = Assembly.LoadFrom(strTempAssmbPath);
//Return the loaded assembly.
return MyAssembly;
}
I had the same issue, if you are working on SharePoint, sometime the references might not get bundled in WSP so, while deploying, these referenced dlls will not be deployed. Resolution is to manually these from the GAC or force these into WSPs or copy them to the local bin. The last one solved for me.