Write your self an Interface (IKnowAboutSomething) that is accessible via your Loaded DLL and also your Loading Program.
Scan through your Loaded DLL and find the classes which implement this interface.
Then you can use Activator.CreateInstance to create an instance of the Types you found (where you know the interface)
Now you just call methods on your IKnowAboutSomething.GetThingINeed() etc and you can interact with things you don't know about at compile time. (Well you know a little bit because they are using the Interface and therefore have an agreement)
Place this code in an External DLL (eg Core.Dll) that is accessible by both projects.
using System.IO;
public interface ISettings
{
/// <summary>
/// Will be called after you Setup has executed if it returns True for a save to be performed. You are given a Stream to write your data to.
/// </summary>
/// <param name="s"></param>
/// <remarks></remarks>
void Save(Stream s);
/// <summary>
/// Will be called before your Setup Method is to enable the loading of existing settings. If there is no previous configuration this method will NOT be called
/// </summary>
/// <param name="s"></param>
/// <remarks></remarks>
void Load(Stream s);
/// <summary>
/// Your plugin must setup a GUID that is unique for your project. The Main Program will check this and if it is duplicated your DLL will not load
/// </summary>
/// <value></value>
/// <returns></returns>
/// <remarks></remarks>
Guid Identifier { get; }
/// <summary>
/// This Description will be displayed for the user to select your Plugin. You should make this descriptive so the correct one is selected in the event they have multiple plugins active.
/// </summary>
/// <value></value>
/// <returns></returns>
/// <remarks></remarks>
string Description { get; }
}
Now in your Main Project add a Reference to the above DLL.
In your main project scan a directory for the DLL's you are planning to load (c:\myDlls*.dll) use a DirectoryInfo (or similar) to scan.
Once you have found a DLL, use the Assembly asm = Assembly.LoadFrom(filename) to get it loaded.
Now you can do this in the main project.
foreach (Type t in asm.GetTypes())
{
if (typeof(ISettings).IsAssignableFrom(t))
{
//Found a Class that is usable
ISettings loadedSetting = Activator.CreateInstance(t);
Console.WriteLine(loadedSetting.Description);
}
}