C# 4.0: casting dynamic to static - c#

This is an offshoot question that's related to another I asked here. I'm splitting it off because it's really a sub-question:
I'm having difficulties casting an object of type dynamic to another (known) static type.
I have an ironPython script that is doing this:
import clr
clr.AddReference("System")
from System import *
def GetBclUri():
return Uri("http://google.com")
note that it's simply newing up a BCL System.Uri type and returning it. So I know the static type of the returned object.
now over in C# land, I'm newing up the script hosting stuff and calling this getter to return the Uri object:
dynamic uri = scriptEngine.GetBclUri();
System.Uri u = uri as System.Uri; // casts the dynamic to static fine
Works no problem. I now can use the strongly typed Uri object as if it was originally instantiated statically.
however....
Now I want to define my own C# class that will be newed up in dynamic-land just like I did with the Uri. My simple C# class:
namespace Entity
{
public class TestPy // stupid simple test class of my own
{
public string DoSomething(string something)
{
return something;
}
}
}
Now in Python, new up an object of this type and return it:
sys.path.append(r'C:..path here...')
clr.AddReferenceToFile("entity.dll")
import Entity.TestPy
def GetTest():
return Entity.TestPy(); // the C# class
then in C# call the getter:
dynamic test = scriptEngine.GetTest();
Entity.TestPy t = test as Entity.TestPy; // t==null!!!
here, the cast does not work. Note that the 'test' object (dynamic) is valid--I can call the DoSomething()--it just won't cast to the known static type
string s = test.DoSomething("asdf"); // dynamic object works fine
so I'm perplexed. the BCL type System.Uri will cast from a dynamic type to the correct static one, but my own type won't. There's obviously something I'm not getting about this...
--
Update: I did a bunch of tests to make sure my assembly refs are all lining up correctly. I changed the referenced assembly ver number then looked at the dynamic objects GetType() info in C#--it is the correct version number, but it still will not cast back to the known static type.
I then created another class in my console app to check to see I would get the same result, which turned out positive: I can get a dynamic reference in C# to a static type instantiated in my Python script, but it will not cast back to the known static type correctly.
--
even more info:
Anton suggests below that the AppDomain assembly binding context is the likely culprit. After doing some tests I think it very likely is. . . but I can't figure out how to resolve it! I was unaware of assembly binding contexts so thanks to Anton I've become more educated on assembly resolution and the subtle bugs that crop up there.
So I watched the assembly resolution process by putting a handler on the event in C# prior to starting the script engine. That allowed me to see the python engine start up and the runtime start to resolve assemblies:
private static Type pType = null; // this will be the python type ref
// prior to script engine starting, start monitoring assembly resolution
AppDomain.CurrentDomain.AssemblyResolve
+= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
... and the handler sets the var pType to the Type that python is loading:
static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
if (args.LoadedAssembly.FullName ==
"Entity, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null")
{
// when the script engine loads the entity assembly, get a reference
// to that type so we can use it to cast to later.
// This Type ref magically carries with it (invisibly as far as I can
// tell) the assembly binding context
pType = args.LoadedAssembly.GetType("Entity.TestPy");
}
}
So while the type used by python is the same on in C#, I'm thinking (as proposed by Anton) that the different binding contexts mean that to the runtime, the two types (the one in the 'load binding context' and the 'loadfrom binding context) are different--so you can't cast on to the other.
So now that I have hold of the Type (along with it's binding context) loaded by Python, lo and behold in C# I can cast the dynamic object to this static type and it works:
dynamic test = scriptEngine.GetTest();
var pythonBoundContextObject =
Convert.ChangeType(test, pType); // pType = python bound
string wow = pythonBoundContextObject .DoSomething("success");
But, sigh, this doesn't totally fix the problem, because the var pythonBoundContextObject while of the correct type, still carries the taint of the wrong assembly binding context. This means that I can't pass this to other parts of my code because we still have this bizzare type mismatch where the invisible specter of binding context stops me cold.
// class that takes type TestPy in the ctor...
public class Foo
{
TestPy tp;
public Foo(TestPy t)
{
this.tp = t;
}
}
// can't pass the pythonBoundContextObject (from above): wrong binding context
Foo f = new Foo(pythonBoundContextObject); // all aboard the fail boat
So the resolution is going to have to be on the Python side: getting the script to load in the right assembly binding context.
in Python, if I do this:
# in my python script
AppDomain.CurrentDomain.Load(
"Entity, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null");
the runtime can't resolve my type:
import Entity.TestPy #fails

Here's an answer from the IronPython team which covers the same problem:
C# / IronPython Interop with shared C# Class Library
(Lifted from http://lists.ironpython.com/pipermail/users-ironpython.com/2010-September/013717.html )

I bet that IronPython loads your entity.dll into a different assembly load context, so that you have two copies of it loaded and the types in them are of course different. You might be able to work around this issue by hooking AppDomain.AssemblyReslove/AppDomain.AssemblyLoad and returning your local assembly (typeof (Entity.TestPy).Assembly) when IronPython tries to load it, but I don't guarantee that this will work.
You don't experience this with System.Uri because mscorlib.dll (and maybe some other system assemblies) is treated specially by the runtime.
Update: IronPython FAQ states that if the assembly isn't already loaded clr.AddReferenceToFile uses Assembly.LoadFile, which loads into the 'Neither' context. Try accessing a method from Entity.TestPy before calling IronPython to load the assembly into the default Load context.

Related

How to find out origin of unknown type

I have a C# function that makes a call to an API. This function returns an untyped object because of reasons.
Now, what I want to do is to cast that object to its actual type. I know what the type is called, but that's about it. Specifically, I can't cast it because I do not know which class I have to import.
So, what I would like to do is this:
object drawing = DrawingSoapLoader.GetDrawing(ITEM_NUMBER, REVISION_CODE, DRAWING_TYPE);
if(drawing is CADDrawing){
CADDrawing cadDrawing = (CADDrawing) drawing;
[...]
}
...however, that does not work because the type CADDrawing is not recognized.
Currently, what I have working instead is this:
object drawing = DrawingSoapLoader.GetDrawing(ITEM_NUMBER, REVISION_CODE, DRAWING_TYPE);
Type type = drawing.GetType();
Assert.AreEqual("CADDrawing", type.Name);
By debugging this, I can see that the type is this:
Name = "CADDrawing"
FullName = "CADDrawing"
Assembly = {gd5rgwpt, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null} System.Reflection.Assembly {System.Reflection.RuntimeAssembly}
I've also confirmed that the assembly code (here "gd5rgwpt") is different every time I run this.
I can find that .dll in my \AppData\Local\Temp folder, and I can even see that it has the CADDrawing type inside, and while I suppose I could just copy that .dll and manually add it to my project, somehow I don't think this is the right way to go about this.
Is there a better way to go about this?
Or is this just a case where it would be better to create a local CADDrawing class and then cast it to that?

Can dll-files be used as plug and play modules [duplicate]

Is it possible to instantiate an object at runtime if I only have the DLL name and the class name, without adding a reference to the assembly in the project? The class implements a interface, so once I instantiate the class, I will then cast it to the interface.
Assembly name:
library.dll
Type name:
Company.Project.Classname
EDIT: I dont have the absolute path of the DLL, so Assembly.LoadFile won't work. The DLL might be in the application root, system32, or even loaded in the GAC.
Yes. You need to use Assembly.LoadFrom to load the assembly into memory, then you can use Activator.CreateInstance to create an instance of your preferred type. You'll need to look the type up first using reflection. Here is a simple example:
Assembly assembly = Assembly.LoadFrom("MyNice.dll");
Type type = assembly.GetType("MyType");
object instanceOfMyType = Activator.CreateInstance(type);
Update
When you have the assembly file name and the type name, you can use Activator.CreateInstance(assemblyName, typeName) to ask the .NET type resolution to resolve that into a type. You could wrap that with a try/catch so that if it fails, you can perform a search of directories where you may specifically store additional assemblies that otherwise might not be searched. This would use the preceding method at that point.
Consider the limitations of the different Load* methods. From the MSDN docs...
LoadFile does not load files into the LoadFrom context, and does not resolve dependencies using the load path, as the LoadFrom method does.
More information on Load Contexts can be found in the LoadFrom docs.
Activator.CreateInstance ought to work.
IFace object = (IFace)Activator.CreateInstance( "AssemblyName",
"TypeName" )
.Unwrap();
Note: The type name must be the fully qualified type.
Example:
var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap();
aray.Add(10);
foreach (object obj in aray)
{
Console.WriteLine(obj);
}
I found this question and some answers very useful, however I did have path problems, so this answer would cover loading library by finding bin directory path.
First solution:
string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFrom(assemblyPath);
Type T = assembly.GetType("Company.Project.Classname");
Company.Project.Classname instance = (Company.Project.Classname) Activator.CreateInstance(T);
Second solution
string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFile(assemblyPath);
(Company.Project.Classname) instance = (Company.Project.Classname) assembly.CreateInstance("Company.Project.Classname");
You can use same principle for interfaces (you would be creating a class but casting to interface), such as:
(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");
This example is for web application but similar could be used for Desktop application, only path is resolved in different way, for example
Path.GetDirectoryName(Application.ExecutablePath)
It's Easy.
Example from MSDN:
public static void Main()
{
// Use the file name to load the assembly into the current
// application domain.
Assembly a = Assembly.Load("example");
// Get the type to use.
Type myType = a.GetType("Example");
// Get the method to call.
MethodInfo myMethod = myType.GetMethod("MethodA");
// Create an instance.
object obj = Activator.CreateInstance(myType);
// Execute the method.
myMethod.Invoke(obj, null);
}
Here's a reference link
https://msdn.microsoft.com/en-us/library/25y1ya39.aspx
Starting from Framework v4.5 you can use Activator.CreateInstanceFrom() to easily instantiate classes within assemblies.
The following example shows how to use it and how to call a method passing parameters and getting return value.
// Assuming moduleFileName contains full or valid relative path to assembly
var moduleInstance = Activator.CreateInstanceFrom(moduleFileName, "MyNamespace.MyClass");
MethodInfo mi = moduleInstance.Unwrap().GetType().GetMethod("MyMethod");
// Assuming the method returns a boolean and accepts a single string parameter
bool rc = Convert.ToBoolean(mi.Invoke(moduleInstance.Unwrap(), new object[] { "MyParamValue" } ));
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Type type = assembly.GetType("MyType");
dynamic instanceOfMyType = Activator.CreateInstance(type);
So in this way you can use functions not with getting methodinfo,and then invoking it.You will do like this instanceOfMyType.MethodName();
But you can't use Intellisense because dynamic types are typed in runtime,not in compile time.
Yes. I don't have any examples that I've done personally available right now. I'll post later when I find some. Basically you'll use reflection to load the assembly and then to pull whatever types you need for it.
In the meantime, this link should get you started:
Using reflection to load unreferenced assemblies at runtime
((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod();
You can load an assembly using *Assembly.Load** methods. Using Activator.CreateInstance you can create new instances of the type you want. Keep in mind that you have to use the full type name of the class you want to load (for example Namespace.SubNamespace.ClassName). Using the method InvokeMember of the Type class you can invoke methods on the type.
Also, take into account that once loaded, an assembly cannot be unloaded until the whole AppDomain is unloaded too (this is basically a memory leak).
Depending how intrinsic this kind of functionality is to your project, you might want to consider something like MEF which will take care of the loading and tying together of components for you.
Yes, it is, you will want to use the static Load method on the Assembly class, and then call then call the CreateInstance method on the Assembly instance returned to you from the call to Load.
Also, you can call one of the other static methods starting with "Load" on the Assembly class, depending on your needs.
You can do this things on this way:
using System.Reflection;
Assembly MyDALL = Assembly.Load("DALL"); //DALL name of your assembly
Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // name of your class
object obj = Activator.CreateInstance(MyLoadClass);
I'm using .net5 (.net core 5). What I need to do is:
static void Main()
{
//...
AppDomain.CurrentDomain.AssemblyResolve += CciBaseResolveEventHandler;
Application.Run(new FormMain());
}
private static Assembly CciBaseResolveEventHandler(object sender, ResolveEventArgs args)
{
return Assembly.LoadFile($#"{Directory.GetCurrentDirectory()}\{nameof(CciBase)}.dll");
}
Change "CciBase" to your dll name.
Make sure the dll is in the same same folder with the exe.
Do it before the main process starts (Application.Run()).

Dynamically load a DLL from a specific folder?

At the moment, I have this code :
var shellViewLibrary = Assembly.LoadFrom(Path.Combine(_DllsPath, _DllShellView));
IEnumerable<Type> types = shellViewLibrary.GetTypes();
foreach (Type type in types)
{
var typeIShellViewInterface = type.GetInterface(_NamespaceIShellView, false);
if (typeIShellViewInterface != null)
{
//here
}
}
The thing is that where I got //here I want to use Activator.CreateInstance to create an object whose type is type in a specific folder (that is outside the build folder)
I tried about 20 different things, most of them with this : http://msdn.microsoft.com/en-us/library/d133hta4.aspx
but none works...
The typical thing I tried is :
object MyObj = Activator.CreateInstance(shellViewLibrary.FullName, type.FullName);
or
object MyObj = Activator.CreateInstance(Path.Combine(_DllsPath, _DllShellView), type.FullName);
I always got different exception, the most common being :
XamlParseException
I feel like that I'm not using Activator.CreateInstance in the right way with 2 parameters. What should I do ?
This is an example of "Dynamically Loading a .dll from a Specific Folder" at runtime.
// Check if user has access to requested .dll.
string strDllPath = Path.GetFullPath(strSomePath);
if (File.Exists(strDllPath))
{
// Execute the method from the requested .dll using reflection (System.Reflection).
Assembly DLL = Assembly.LoadFrom(strDllPath);
Type classType = DLL.GetType(String.Format("{0}.{1}", strNmSpaceNm, strClassNm));
if (classType != null)
{
// Create class instance.
classInst = Activator.CreateInstance(classType);
// Invoke required method.
MethodInfo methodInfo = classType.GetMethod(strMethodName);
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(classInst, new object[] { dllParams });
return result.ToString();
}
}
}
This took me a while to work out so I hope it is of some use...
Once you call this line
var shellViewLibrary = Assembly.LoadFrom(Path.Combine(_DllsPath, _DllShellView));
The assembly has been loaded in to memory. So long as you specify types correctly from this then you will be able to use Activator.CreateInstance to create the types. ie: It is not necessary to further specify where the type is.
Regarding Activator, from MSDN the CreateInstance method can accept a System.Type. I would just use this method inside your if-statement:
Activator.CreateInstance(Type type);
What I would try to do to debug this is first create the type and then pass it in to CreateInstance. You may find that the Type creation itself is failing (due to unresolved assembly) or the instantiation of that type (due to exception in the constructor). At first glance your code here appears to be correct:
foreach (Type type in types)
{
var typeIShellViewInterface = type.GetInterface(_NamespaceIShellView, false);
if (typeIShellViewInterface != null)
{
try
{
// I assume you are calling this line at the point marked 'here'.
// To debug the creation wrap in a try-catch and view the inner exceptions
var result = Activator.CreateInstance(type);
}
catch(Exception caught)
{
// When you hit this line, look at caught inner exceptions
// I suspect you have a broken Xaml file inside WPF usercontrol
// or Xaml resource dictionary used by type
Debugger.Break();
}
}
}
In your question you specify that you are getting a XamlParseException. It sounds to me like the type in question is a UserControl (or otherwise refers to a WPF Xaml resource file) and there is an error in that Xaml file, i.e. nothing to do with your usage of Assembly.Load or Activator.CreateInstance.
Could you try posting the inner exception(s) to get a better idea on what the problem is?
Check out MEF and Prism. MEF is a dependency injection library that helps with this. You can load all of your dependencies from a specific folder and make dynamically load them.
Prism is a pattern that leverages dependency injection and works great with MEF to load libraries dynamically
if you're trying to create a type with the Activator class from a DLL that's outside your application, you need to first load this DLL inside your application domain.
The easiest and quickest way to do this is by using the Assembly.LoadFile method.
more information about that method can be found here : http://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadfile.aspx
When the assembly is properly loaded you can use the Activator to create an instance from the type inside the DLL.
We use this mechanic to run custom code in our application.
I'm not sure what you mean by this:
create an object whose type is type in a specific folder (that is outside the build folder)
A type only exists in an assembly. Path is entirely irrelevant to types in .NET
I assume that by "path" you really mean "namespace", meaning that you don't know in which namespace the type exists. You have already loaded the assembly in your code. Inspect the assembly using reflection to find the type you're looking for. Then pass the Type object that represents the type you're looking for to Activator.CreateInstance

Dynamically Loading a DLL

I am trying to simply load a dll written in C# at run time and create an instance of a class in that dll.
Assembly a = Assembly.LoadFrom(#"C:\Development\DaDll.dll");
Type type = a.GetType("FileReleaseHandler", true);
TestInterface.INeeedHelp handler = Activator.CreateInstance(type) as TestInterface.INeeedHelp;
No errors are thrown, and if I step through the code I can walk though the FileReleaseHandler Class as it executes the constructor but the value of handler is always null.
What am I missing here? or even is there a better way I should be going about this?
Where is TestInterface.INeedHelp defined? One common problem is if you've got the same interface in multiple assemblies. If both the caller and the dynamically loaded assembly reference the same interface in the same assembly, it should be okay.
One subtlety is that if the assembly is in a different directory to the calling assembly, it may end up loading a different copy of the same assembly, which can be very irritating :(
Try setting the result of Activator.CreateInstance to an object directly, and not casting.
It's possible FileReleaseHandler does not implement TestInterface.INeeedHelp, in which case, this will be set to null via the "as TestInterface.INeeedHelp".
Check the assemblies that are loaded into the application domain. Are there two assemblies with the TestInterface.INeedHelp interface in it? My suspicion is that the LoadFrom is binding this created object to a different TestInterface.INeedHelp than the one to which you are trying to cast. Try doing a normal downcast rather than a so-called "safe" cast and see what error you get.
The problem is that the LoadFrom method loads the dll into "LoadFrom" context which is different from the default context. The rules of type resolution for the types in this context differ from the ones you are used to. It is possible that the INeedHelp interface as defined in your main module from the standpoint of the runtime is different from the interface with the same name as coming from the LoadFrom context. This will cause the cast (as TestINterface) return null.
To see if this is the case try to assign the result to an object.
I would do something like :
Assembly a = Assembly.LoadFrom(#"C:\Development\DaDll.dll");
object obj = a.CreateInstance("fullClassName",other params) as IMyType
//(if it implements an interface you referenced)

Can I load a .NET assembly at runtime and instantiate a type knowing only the name?

Is it possible to instantiate an object at runtime if I only have the DLL name and the class name, without adding a reference to the assembly in the project? The class implements a interface, so once I instantiate the class, I will then cast it to the interface.
Assembly name:
library.dll
Type name:
Company.Project.Classname
EDIT: I dont have the absolute path of the DLL, so Assembly.LoadFile won't work. The DLL might be in the application root, system32, or even loaded in the GAC.
Yes. You need to use Assembly.LoadFrom to load the assembly into memory, then you can use Activator.CreateInstance to create an instance of your preferred type. You'll need to look the type up first using reflection. Here is a simple example:
Assembly assembly = Assembly.LoadFrom("MyNice.dll");
Type type = assembly.GetType("MyType");
object instanceOfMyType = Activator.CreateInstance(type);
Update
When you have the assembly file name and the type name, you can use Activator.CreateInstance(assemblyName, typeName) to ask the .NET type resolution to resolve that into a type. You could wrap that with a try/catch so that if it fails, you can perform a search of directories where you may specifically store additional assemblies that otherwise might not be searched. This would use the preceding method at that point.
Consider the limitations of the different Load* methods. From the MSDN docs...
LoadFile does not load files into the LoadFrom context, and does not resolve dependencies using the load path, as the LoadFrom method does.
More information on Load Contexts can be found in the LoadFrom docs.
Activator.CreateInstance ought to work.
IFace object = (IFace)Activator.CreateInstance( "AssemblyName",
"TypeName" )
.Unwrap();
Note: The type name must be the fully qualified type.
Example:
var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap();
aray.Add(10);
foreach (object obj in aray)
{
Console.WriteLine(obj);
}
I found this question and some answers very useful, however I did have path problems, so this answer would cover loading library by finding bin directory path.
First solution:
string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFrom(assemblyPath);
Type T = assembly.GetType("Company.Project.Classname");
Company.Project.Classname instance = (Company.Project.Classname) Activator.CreateInstance(T);
Second solution
string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFile(assemblyPath);
(Company.Project.Classname) instance = (Company.Project.Classname) assembly.CreateInstance("Company.Project.Classname");
You can use same principle for interfaces (you would be creating a class but casting to interface), such as:
(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");
This example is for web application but similar could be used for Desktop application, only path is resolved in different way, for example
Path.GetDirectoryName(Application.ExecutablePath)
It's Easy.
Example from MSDN:
public static void Main()
{
// Use the file name to load the assembly into the current
// application domain.
Assembly a = Assembly.Load("example");
// Get the type to use.
Type myType = a.GetType("Example");
// Get the method to call.
MethodInfo myMethod = myType.GetMethod("MethodA");
// Create an instance.
object obj = Activator.CreateInstance(myType);
// Execute the method.
myMethod.Invoke(obj, null);
}
Here's a reference link
https://msdn.microsoft.com/en-us/library/25y1ya39.aspx
Starting from Framework v4.5 you can use Activator.CreateInstanceFrom() to easily instantiate classes within assemblies.
The following example shows how to use it and how to call a method passing parameters and getting return value.
// Assuming moduleFileName contains full or valid relative path to assembly
var moduleInstance = Activator.CreateInstanceFrom(moduleFileName, "MyNamespace.MyClass");
MethodInfo mi = moduleInstance.Unwrap().GetType().GetMethod("MyMethod");
// Assuming the method returns a boolean and accepts a single string parameter
bool rc = Convert.ToBoolean(mi.Invoke(moduleInstance.Unwrap(), new object[] { "MyParamValue" } ));
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Type type = assembly.GetType("MyType");
dynamic instanceOfMyType = Activator.CreateInstance(type);
So in this way you can use functions not with getting methodinfo,and then invoking it.You will do like this instanceOfMyType.MethodName();
But you can't use Intellisense because dynamic types are typed in runtime,not in compile time.
Yes. I don't have any examples that I've done personally available right now. I'll post later when I find some. Basically you'll use reflection to load the assembly and then to pull whatever types you need for it.
In the meantime, this link should get you started:
Using reflection to load unreferenced assemblies at runtime
((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod();
You can load an assembly using *Assembly.Load** methods. Using Activator.CreateInstance you can create new instances of the type you want. Keep in mind that you have to use the full type name of the class you want to load (for example Namespace.SubNamespace.ClassName). Using the method InvokeMember of the Type class you can invoke methods on the type.
Also, take into account that once loaded, an assembly cannot be unloaded until the whole AppDomain is unloaded too (this is basically a memory leak).
Depending how intrinsic this kind of functionality is to your project, you might want to consider something like MEF which will take care of the loading and tying together of components for you.
Yes, it is, you will want to use the static Load method on the Assembly class, and then call then call the CreateInstance method on the Assembly instance returned to you from the call to Load.
Also, you can call one of the other static methods starting with "Load" on the Assembly class, depending on your needs.
You can do this things on this way:
using System.Reflection;
Assembly MyDALL = Assembly.Load("DALL"); //DALL name of your assembly
Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // name of your class
object obj = Activator.CreateInstance(MyLoadClass);
I'm using .net5 (.net core 5). What I need to do is:
static void Main()
{
//...
AppDomain.CurrentDomain.AssemblyResolve += CciBaseResolveEventHandler;
Application.Run(new FormMain());
}
private static Assembly CciBaseResolveEventHandler(object sender, ResolveEventArgs args)
{
return Assembly.LoadFile($#"{Directory.GetCurrentDirectory()}\{nameof(CciBase)}.dll");
}
Change "CciBase" to your dll name.
Make sure the dll is in the same same folder with the exe.
Do it before the main process starts (Application.Run()).

Categories

Resources