Unit Testing code that uses a separate AppDomain

I have code that uses an AppDomain to dynamically load plugins. I have a private internal class called PluginFinder to do the work. This all works in the production environment, but I am now trying to write MS Unit Tests for it, and I am getting an error saying the assembly could not be found.

I have code that uses an AppDomain to dynamically load plugins. I have a private internal class called PluginFinder to do the work. This all works in the production environment, but I am now trying to write MS Unit Tests for it, and I am getting an error saying the assembly could not be found.

To be clear, the main class creates the AppDomain and runs the PluginFinder in it to load classes it finds with the correct Interface. Once the classes are loaded, control returns to the default AppDomain. The PluginFinder is only used during loading.

I use the code below to create the environment:

            //  Create a domain to text for plugins
            AppDomain domain = AppDomain.CreateDomain("PluginLoader");
        //  Set PluginFinder to run in the new domain (assemblyName, typeName)
        (PluginFinder)domain.CreateInstanceAndUnwrap(
            typeof(PluginFinder).Assembly.FullName, typeof(PluginFinder).FullName);

PluginFinder uses a default constructor, and is a private internal class. The exception I get is below:

    ------ Exception ------
Error: Could not load file or assembly 'MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
There was an error creating the Plugin Loader.
Could not load file or assembly 'MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Activator.CreateInstance(String assemblyString, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(String assemblyName, String typeName)
at System.AppDomain.CreateInstance(String assemblyName, String typeName)
at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName)
at MyClass.loadPlugins() in C:\Code...
---- End Exception ----

I have found this solution, which suggests that NUnit runs in multiple AppDomains, which makes testing of AppDomains impossible without plugins. I'm using MS Unit Test, but I suspect that this may be the case here as well.

**** RESOLVED ****

As was mentioned in the comment below, I needed to use the overload constructor. I modified my code (shown below), and it worked.

// Set up the AppDomainSetup
var setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

// Set up the Evidence
var baseEvidence = AppDomain.CurrentDomain.Evidence;

// Create a domain to text for plugins
AppDomain domain = AppDomain.CreateDomain("PluginLoader", baseEvidence, setup);

// Set PluginFinder to run in the new domain (assemblyName, typeName)
PluginFinder finder = (PluginFinder)domain.CreateInstanceAndUnwrap(
typeof(PluginFinder).Assembly.FullName, typeof(PluginFinder).FullName);


Visual Studio Windows Forms C# Interop.Excel - Excel Class Object

I have created a C# Windows Form project in Visual Studio and I am trying to work with an Excel workbook via interop.excel. I have created a custom "excel class" and created an object of it in my Form1. What I am struggling with is whether it is possible to open an excel workbook via a button press, i.e. create the class object from a button press, and then be able to use that object in other button presses. Two versions of code are shown below. One works. One does not. The one that works just opens the Excel workbook when the program is launched. The other attempts to use a button press on the form to open the workbook after the program is launched. In the code that does not work, the object "does not exist in the current context". Any help on how to make the button press code work is most appreciated!

I have created a C# Windows Form project in Visual Studio and I am trying to work with an Excel workbook via interop.excel. I have created a custom "excel class" and created an object of it in my Form1. What I am struggling with is whether it is possible to open an excel workbook via a button press, i.e. create the class object from a button press, and then be able to use that object in other button presses. Two versions of code are shown below. One works. One does not. The one that works just opens the Excel workbook when the program is launched. The other attempts to use a button press on the form to open the workbook after the program is launched. In the code that does not work, the object "does not exist in the current context". Any help on how to make the button press code work is most appreciated!

This code works:

namespace XLtest1
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
ExcelClass ex  = new ExcelClass(@"C:\path\TestBook.xlsx", 1);

private void ReadCell_Click(object sender, EventArgs e)
{
    ex.ReadCell();
}

...

This code does not:

namespace XLtest1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public void OpenFile()
{
    ExcelClass ex  = new ExcelClass(@"C:\path\TestBook.xlsx", 1);
}

private void OpenWorkbook_Click(object sender, EventArgs e)
{
  OpenFile();
}

private void ReadCell_Click(object sender, EventArgs e)
{
    ex.ReadCell(); // "ex" does not exist in the current context 
}


Accelerate your C++ development (with Visual Studio 2019)

Join us for a demo-heavy rundown of all the reasons you should be excited about Visual Studio 2019 for C++ development. Learn about all that is new, from updates to the CMake integration for targeting Windows and Linux, to C++ productivity, performance and build throughput improvements as well as our progress on C++20 conformance.CMake integration for targeting Windows and Linux, to C++ productivity, performance and build throughput improvements as well as our progress on C++20 conformance.

Join us for a demo-heavy rundown of all the reasons you should be excited about Visual Studio 2019 for C++ development. Learn about all that is new, from updates to the CMake integration for targeting Windows and Linux, to C++ productivity, performance and build throughput improvements as well as our progress on C++20 conformance.CMake integration for targeting Windows and Linux, to C++ productivity, performance and build throughput improvements as well as our progress on C++20 conformance.

Learn More

Unreal Engine C++ Developer: Learn C++ and Make Video Games

Learn C++ Programming -Beginner to Advance- Deep Dive in C++

Learn C++ Programming from Beginner to Expert : 2019

Learn OOP C# Programming Techniques and Methods with Object Orientated Programming

VS Code: C++ Development with Visual Studio Code

Bring Some C++ to Xamarin Apps

Create a C# Application from Start to Finish - Complete Course

VS Code: C++ Development with Visual Studio Code

If you’re looking for a fast and lightweight code editor, Visual Studio Code has you covered. Come get an overview of Visual Studio Code along with the C++ extension that enables editing, building, and debugging your C++ code across Windows, Mac, and Linux.



Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter