Reputation: 9394
I need to load an assembly from a certain location and not from the GAC. I can not remove the assembly from the GAC, because my program has to run on different machines, where I couldn't control if the assembly is in the GAC or not.
I added a reference to the DLL-File to my project. Unfortuntely the assembly is loaded from the GAC.
I've tried the following code in my App.xaml.cs
in the Startup
-Event
var directory = Thread.GetDomain().BaseDirectory;
var dllPath = Path.Combine(directory, "MyAssembly.dll");
var assembly = Assembly.LoadFrom(dllPath);
Unfortunately the assembly is still loaded from the GAC.
What can I do to load it from the given location, even if the assembly is in GAC?
Upvotes: 10
Views: 34882
Reputation: 4259
Take a look at ILMerge (article Merging .NET assemblies using ILMerge )
It should allow you to merge the DLL with your code, so nothing external will be downloaded and you don't pay reflection cost so performance should be better.
ILMerge takes a set of input assemblies and merges them into one target assembly. The first assembly in the list of input assemblies is the primary assembly. When the primary assembly is an executable, then the target assembly is created as an executable with the same entry point as the primary assembly. Also, if the primary assembly has a strong name, and a .snk file is provided, then the target assembly is re-signed with the specified key so that it also has a strong name.
Another option is to remove strong name from that DLL. Look here Assembly Manipulation in C#
Reflexil is able to remove assembly strong name and update referencing assemblies. You can also do it by yourself with the assembly editor: remove the public key and set the HasPublicKey flag to false.
Upvotes: 0
Reputation: 32568
Unfortunately, you won't be able to bypass the GAC - Assembly.LoadFrom()
, Assembly.LoadFile()
, and even loading it into a byte array and using Assembly.Load(byte[])
will all check the GAC first for an assembly with the same identity, and load it instead.
You used to be able to do what you want in .net 1.1, but since 2.0, the GAC is checked first. See How the Runtime Locates Assemblies - note that step 3 is check the GAC, before probing directories (even if you you fully specified it)
If you want to load one up for Reflection (examining the assembly, rather than running it), you can use Assembly.ReflectionOnlyLoadFrom()
Upvotes: 24
Reputation: 61812
Check out Assembly.LoadFrom()
on MSDN.
From MSDN:
Assembly SampleAssembly;
SampleAssembly = Assembly.LoadFrom("c:\\Sample.Assembly.dll");
// Obtain a reference to a method known to exist in assembly.
MethodInfo Method = SampleAssembly.GetTypes()[0].GetMethod("Method1");
// Obtain a reference to the parameters collection of the MethodInfo instance.
ParameterInfo[] Params = Method.GetParameters();
// Display information about method parameters.
// Param = sParam1
// Type = System.String
// Position = 0
// Optional=False
foreach (ParameterInfo Param in Params)
{
Console.WriteLine("Param=" + Param.Name.ToString());
Console.WriteLine(" Type=" + Param.ParameterType.ToString());
Console.WriteLine(" Position=" + Param.Position.ToString());
Console.WriteLine(" Optional=" + Param.IsOptional.ToString());
}
Even after loading your custom assembly, you cannot simply invoke your method or use types as you normally would. Check out this example, stolen from this question, which should point you in the right direction:
Assembly assembly = Assembly.LoadFile("myAssembly");
Type type = assembly.GetType("myAssembly.ClassName");
if (type != null)
{
MethodInfo methodInfo = type.GetMethod("MyMethod");
if (methodInfo != null)
{
object result = null;
ParameterInfo[] parameters = methodInfo.GetParameters();
object classInstance = Activator.CreateInstance(type, null);
if (parameters.Length == 0)
{
//This works fine
result = methodInfo.Invoke(classInstance, null);
}
else
{
object[] parametersArray = new object[] { "Hello" };
//The invoke does NOT work it throws "Object does not match target type"
result = methodInfo.Invoke(classInstance, parametersArray);
}
}
}
Upvotes: 7