I'm studing C#. I read books of Andrew Troelsen "C# and the .NET Platform" and Jeffrey Richter's "CLR via C#". Now, I'm trying to make application, which will load assemblies from some directory, push them to AppDomain's and run the method's included (the application which supports plug-ins). Here is the DLL where is the common interface. I add it to my application, and in all DLLs with plugins. MainLib.DLL
namespace MainLib
{
public interface ICommonInterface
{
void ShowDllName();
}
}
Here is plugins: PluginWithOutException
namespace PluginWithOutException
{
public class WithOutException : MarshalByRefObject, ICommonInterface
{
public void ShowDllName()
{
MessageBox.Show("PluginWithOutException");
}
public WithOutException()
{
}
}
}
and another one: PluginWithException
namespace PluginWithException
{
public class WithException : MarshalByRefObject, ICommonInterface
{
public void ShowDllName()
{
MessageBox.Show("WithException");
throw new NotImplementedException();
}
}
}
And here is an application, which loads DLLs and runs them in another AppDomain's
namespace Plug_inApp
{
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(CreateDomainAndLoadAssebly, @"E:\Plugins\PluginWithException.dll");
Console.ReadKey();
}
public static void CreateDomainAndLoadAssebly(object name)
{
string assemblyName = (string)name;
Assembly assemblyToLoad = null;
AppDomain domain = AppDomain.CreateDomain(string.Format("{0} Domain", assemblyName));
domain.FirstChanceException += domain_FirstChanceException;
try
{
assemblyToLoad = Assembly.LoadFrom(assemblyName);
}
catch (FileNotFoundException)
{
MessageBox.Show("Can't find assembly!");
throw;
}
var theClassTypes = from t in assemblyToLoad.GetTypes()
where t.IsClass &&
(t.GetInterface("ICommonInterface") != null)
select t;
foreach (Type type in theClassTypes)
{
ICommonInterface instance = (ICommonInterface)domain.CreateInstanceFromAndUnwrap(assemblyName, type.FullName);
instance.ShowDllName();
}
}
static void domain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
}
}
}
I expect, that if I run instance.ShowDllName();
in another domain (maybe I do it wrong?) the unhandled exception will drop the domain where it runs, but the default domain will work. But in my case - default domain crashes after exception occurs in another domain. Please, tell me what I'm doing wrong?