My project contains
windows form application(WindowsFormsApplication1)
dll (ClassLibrary1).
I am trying to implement some logic in my windows form application when an event is raised in my DLL. I am accessing DLL methods through AppDomain.
Below is the code in windows form Form1.cs
using System;
// more usings ...
using ClassLibrary1;
using System.Reflection;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
trial obj = new trial();
obj.trial1();
}
}
class trial
{
void HandleEvent(object sender, EventArgs e)
{
Console.WriteLine("HandleEvent called");
}
AppDomain ad = AppDomain.CreateDomain("Test");
string DLL = @"C:\..\ClassLibrary1.dll";
public void trial1()
{
trial pro = new trial();MethodInfo method = typeof(trial).GetMethod("HandleEvent", BindingFlags.NonPublic | BindingFlags.Instance);
// Subscribe to the event
EventInfo eventInfo = typeof(ClassLibrary1.Class1).GetEvent("TestEvent");
Type type = eventInfo.EventHandlerType;
Delegate handler = Delegate.CreateDelegate(type, pro, method);
// method call 1
Loader.Call(ad, DLL,"ClassLibrary1.Class1","RaiseEvent",DateTime.Now.ToShortDateString());
}
}
public class Loader : MarshalByRefObject
{
object CallInternal(string dll, string typename, string method, object[] parameters)
{
Assembly a = Assembly.LoadFile(dll);
object o = a.CreateInstance(typename);
Type t = o.GetType();
MethodInfo m = t.GetMethod(method);
return m.Invoke(o, parameters);
}
public static object Call(AppDomain domain, string dll, string typename, string method, params object[] parameters)
{
Loader ld = (Loader)domain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Loader).FullName);
object result = ld.CallInternal(dll, typename, method, parameters);
AppDomain.Unload(domain);
return result;
}
}
}
Below is the code in ClassLibrary1.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassLibrary1
{
public class Class1
{
public event EventHandler TestEvent;
public int RaiseEvent(string msg)
{
try
{
TestEvent(this, EventArgs.Empty);
}
catch (Exception ex)
{
Console.WriteLine("the exception is: " + ex.ToString());
if (ex.InnerException != null)
{
Console.WriteLine("the inner exception is: " + ex.InnerException.Message.ToString());
}
}
return 2;
}
}
}
It throws an exception when it runs TestEvent(this, EventArgs.Empty); The exception is 'Object reference not set to an instance of an object.'
There are no issues when accessing the same event using a console application program. The code in the console application program are as follows.
using System;
using System.Reflection;
class Test
{
void HandleEvent(object sender, EventArgs e)
{
Console.WriteLine("HandleEvent called");
}
static void Main()
{
Test test = new Test();
ClassLibrary1.Class1 publisher = new ClassLibrary1.Class1();
MethodInfo method = typeof(Test).GetMethod("HandleEvent", BindingFlags.NonPublic | BindingFlags.Instance);
// Subscribe to the event
EventInfo eventInfo = typeof(ClassLibrary1.Class1).GetEvent("TestEvent");
Type type = eventInfo.EventHandlerType;
Delegate handler = Delegate.CreateDelegate(type, test, method);
eventInfo.AddEventHandler(publisher, handler);
publisher.RaiseEvent("hello");
}
}
Any help will be very much appreciated. Thank you.