Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to assign an interface to an object at runtime?

After reflecting upon all the great answers I received to my previous question about modeling my code to maximize code re-use, I started wondering if it would be possible to assign the interface to an object at runtime instead of when it is coded.

Take, for example, a simplified portion of code from my previous question:

public class OutboxManager
{
    private IVendorMessenger _VendorMessenger;

    //This is the default constructor, forcing the consumer to provide
    //the implementation of IVendorMessenger.
    public OutboxManager(IVendorMessenger messenger)
    {
         _VendorMessenger = messenger;
    }

    public void DistributeOutboxMessages()
    {
        VendorMessenger.SendMessageToVendor()
                      _OutboxMgrDataProvider.MarkMessageAsProcessed(om)
    }

}

Currently, if someone wants to consume this class, they have to code a class that implements IVendorMessenger and provide it during initialization as a parameter:

 var MyOutboxManger = new OutboxManager(new MyVendorMessenger())

What if, instead of hard-coding the interface parameter, it instead gets assinged at runtime? This way, I could compile a dll for a class that implements IVendorMessenger, drop it into the same folder that OutboxManagerExecutable exists, and it will wire everything up at run time. I suppose, using this logic, I could figure out a way to drop multiple implementations of IVendorMessenger in the same folder and design the executable to be smart enough to iterate through all appropriate dlls and consume them accordingly.

Is this type of functionality possible in .NET 4?

like image 480
Ben McCormack Avatar asked Jan 22 '23 16:01

Ben McCormack


2 Answers

Check out the Managed Extensibility Framework (MEF). It can automatically compose the dependencies of your application just as you describe. It shipped with .NET 4.0.

like image 115
Kent Boogaart Avatar answered Jan 28 '23 13:01

Kent Boogaart


This is a pretty common use case for reflection. The .NET API gives you the pieces you need to:

  1. Find all of the .dlls in a directory: Directory.GetFiles()
  2. Load those assemblies at runtime: Assembly.LoadFile()
  3. Iterate through the types in each assembly: Assembly.GetTypes()
  4. For each type, see if it implements your interface: Type.IsAssignableFrom()
  5. If it does, get and invoke its constructor to create one: Type.GetConstructor()

After that, you've got an Object that you can cast to IVendorMessenger and pass it in.

like image 44
munificent Avatar answered Jan 28 '23 14:01

munificent