Sounds a lot like a thread I wrote ages ago? Would you be looking for this:
http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/CSPluginExample2.zip
I actually ported that to the latest .NET framework the other day. The code more or less still works (although I had to create new project files because for some unknown reason I couldn't get the project files to upgrade successfully - and couldn't be bothered to find out why). If you want to avoid the compiler warnings, modify the code like so:
[source]
public static bool ExecuteVB(string source)
{
VBCodeProvider prov = new VBCodeProvider();
return ExecuteScript(prov, source);
}
public static bool ExecuteCS(string source)
{
CSharpCodeProvider prov = new CSharpCodeProvider();
return ExecuteScript(prov, source);
}
private static bool ExecuteScript(CodeDomProvider compiler, string code)
{
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
//
// add any default libs you want to expose to the scripting API
//
cp.ReferencedAssemblies.Add("system.dll");
cp.ReferencedAssemblies.Add("system.data.dll");
cp.ReferencedAssemblies.Add("system.drawing.dll");
cp.ReferencedAssemblies.Add("system.windows.forms.dll");
//
// add reference to the core dll(s) of the application. The scripts
// will then be able to access the core functionality of the APP.
//
cp.ReferencedAssemblies.Add("CoreAPI.dll");
CompilerResults cr;
cr = compiler.CompileAssemblyFromSource(cp, code);
// check for any errors in the script
if (cr.Errors.HasErrors)
{
StringBuilder sbErr;
sbErr = new StringBuilder();
foreach (CompilerError err in cr.Errors)
{
sbErr.AppendFormat("{0} at line {1} column {2} ",
err.ErrorText,
err.Line,
err.Column);
sbErr.Append("\n");
}
MessageBox.Show(sbErr.ToString(), "Script - Error");
return false;
}
// get the assembly code generated
Assembly a = cr.CompiledAssembly;
try
{
return InvokeAssembly(a);
}
catch (Exception ex)
{
// this is called if an error gets generated when running the script
MessageBox.Show(ex.Message);
}
return false;
}
[/source]
The basic premise is that you define the base types in the API.dll, load the plugin assembly, and then use reflection to hunt for any classes in the plugin that support any of your supported interfaces. It's probably easier to do this with interfaces rather than base classes!
\edit
Found the original thread: http://www.gamedev.net/topic/473195-saveload-as-plugin/