Appdomain for assembly loading (plugins) help

  • Thread starter Thread starter k7s41gx
  • Start date Start date
K

k7s41gx

Guest
Thanks for looking at my question.

The issue I seem to be having is transferring this code into something that creates each plugin on a new appdomain so I can unload and load at will. I have very little experience with AppDomains, but I have attempted some code, also below. Therefore my question is, how do I load each assembly on its on AppDomain, and how do I create a running list of the plugins?


Code 1:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;

namespace SYSAdmin
{
public class PluginLoader
{
public static List<IPlugin> Plugins { get; set; }

public void LoadPlugins()
{
Plugins = new List<IPlugin>();

//Load the DLLs from the Plugins directory
if (Directory.Exists(Constants.FolderName))
{
string[] files = Directory.GetFiles(Constants.FolderName);
foreach (string file in files)
{
if (file.EndsWith(".dll"))
{
Assembly.LoadFile(Path.GetFullPath(file));
//Assembly.Load(File.ReadAllBytes(Path.GetFullPath(file)));
}
}
}

Type interfaceType = typeof(IPlugin);
//Fetch all types that implement the interface IPlugin and are a class
Type[] types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass)
.ToArray();
foreach (Type type in types)
{
//Create a new instance of all found types
Plugins.Add((IPlugin)Activator.CreateInstance(type));
}
}
}
}



Code 2 Experimental Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace SYSAdmin
{
public class test
{
public static List<IPlugin> Plugins { get; set; }
public void xmark()
{
Plugins = new List<IPlugin>();
if (Directory.Exists(Constants.FolderName))
{
string[] files = Directory.GetFiles(Constants.FolderName);
foreach (string file in files)
{
if (file == "TestPlug.dll")
{
AppDomain ad2 = AppDomain.CreateDomain(file);
ad2.Load(Path.GetFullPath(file));
}
}
}
}
}
}



IPlugin Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SYSAdmin
{
public interface IPlugin
{
string Name { get; }
string Explanation { get; }
void Go(string parameters);
}
}




TestPlug.dll Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SYSAdmin;
using System.Windows.Forms;

namespace TestPlugin
{
public class TestPlug : IPlugin
{
public string Explanation
{
get
{
return "Tests functionality of the assembly reference.";
}
}

public string Name
{
get
{
return "TestPlug";
}
}

public void Go(string parameters)
{
string line = parameters;
SYSAdmin.Program.form1.output.AppendText(Environment.NewLine);
SYSAdmin.Program.form1.output.AppendText(line);

}
}
}

As of right now I have a working plugin system but what I've found states you cannot unload an assembly from a running domain. Therefore each plugin having its own app domain would be ideal as then I can load or unload at will.

-K7

Continue reading...
 
Back
Top