Sunday, May 18, 2014

REPLACE YOUR REFLECTION CODE WITH MEF

Whenever I need to load assemblies dynamically at runtime I have up to this date been using the Reflection Namespace somewhat like this:
// Use the file name to load the assembly into the current application domain.
Assembly a = Assembly.Load("example");
// Get the type to use.
Type myType = a.GetType("Example");
// Get the method to call.
MethodInfo myMethod = myType.GetMethod("MethodA");
// Create an instance.
MyClass obj = Activator.CreateInstance(myType) as MyClass;
// Execute the method.
myMethod.Invoke(obj, null);
By using this approach I need to iterate over all my assemblies in order to load objects implementing a certain interface if the assembly name is not known at this time.
However, I discussed this with a colleague and found out there is another way of loading assemblies at runtime. The alternative is called MEF and is shipped with the .Net framework since version 4.0. The magic happens inside the Microsoft.Composition namespace.
Basically, types that should be loaded at runtime is attributed with Export.
[Export(typeof(IPlayer))]
public class TobiasPlayer : IPlayer
{
...
}
Put the assembly where TobiasPlayer is located in a directory accessible by your application. Then, in your application code:

public List GetPlayers()
{
var players = new List();
// Set up MEF
var myPath = @"C:\temp";
var catalog = new DirectoryCatalog(myPath);
var container = new CompositionContainer(catalog);
// Import the exported classes
players.AddRange(container.GetExportedValues());
return players;
}
The GetPlayers method is returning initialized objects of all the types implementing IPlayer and attributed with Export from within the c:\temp directory. The example above uses the GetExportedValues method which instantiates the Export classes. By using GetExports() you receive Lazy objects meaning the objects will be initialized when calling Value on the Lazy object.
This way I don´t have to write code that iterates over all assemblies and can have my assemblies in a separate directory rather than putting them in the web applications bin folder.

No comments:

Post a Comment