I am trying to implement inversion of control (IoC) in order to develop a plug-in based application, which needs to be able to pass data (e.g. strings) back to my main EXE when something happens. To achieve this, I am passing an Action
to the DLL which it can use to send data back to the EXE. The following code shows a little test application to explain my beginner-problem:
namespace MainExe
{
class Program
{
[Import(typeof(IDataProvider))]
public IDataProvider stringProvider { get; set; }
public void myCallback(string str)
{
Console.WriteLine(str);
}
public Program()
{
try
{
AggregateCatalog aggregatecatalogue = new AggregateCatalog();
aggregatecatalogue.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));
CompositionContainer container = new CompositionContainer(aggregatecatalogue);
container.ComposeParts(this);
}
catch (FileNotFoundException fnfex)
{
Console.WriteLine(fnfex.Message);
}
catch (CompositionException cex)
{
Console.WriteLine(cex.Message);
}
}
void Run()
{
if (stringProvider != null)
{
stringProvider.SaySomething("myrequest", myCallback);
Console.ReadKey();
}
}
static void Main(string[] args)
{
Program program = new Program();
program.Run();
}
}
}
My Interface looks like this:
namespace DataInterfaceDll
{
public interface IDataProvider
{
void SaySomething(string request, Action<string> callback);
}
}
And this is the Plug-In (DLL), which should be able to send something back to the EXE (or call a function from the EXE that does this):
namespace StringDataDll
{
[Export(typeof(IDataProvider))]
public class StringData : IDataProvider
{
public void SaySomething(string request, Action<string> callback)
{
callback("This is just a test program...");
}
}
}
When I run this code, I get a System.Reflection.ReflectionTypeLoadException
in the following line
container.ComposeParts(this);
Can anyone tell me what I am doing wrong here?
It works for me by loading dynamically the DLL.
aggregatecatalogue.Catalogs.Add(new AssemblyCatalog(Assembly.LoadFile("yourpath\StringDataDll.dll")));
aggregatecatalogue.Catalogs.Add(new AssemblyCatalog(Assembly.GetAssembly(typeof(IDataProvider))));
And it works too with new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory)
when you copy the stringDataDll.dll in the output folder of your main program.
Be sure to have all of your dll files in your output folder of your main program.