Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Inject Dependencies to Dynamically Loaded Assemblies

I have a manager class that loads various plug-in modules contained in separate assemblies through reflection. This modules are communication to the outside world (WebAPI, various other web protocols).

public class Manager
{
   public ILogger Logger; // Modules need to access this.

   private void LoadAssemblies()
   {
     // Load assemblies through reflection.
   }
}

These plug-in modules must communicate with an object contained within the manager class. How can I implement this? I thought about using dependency injection/IoC container, but how can I do this across assemblies?

Another thought that I had, that I am not thrilled with, is to have the modules reference a static class containing the resource that they need.

I appreciate any constructive comments/suggestions.

like image 444
joek1975 Avatar asked Dec 19 '13 23:12

joek1975


People also ask

How do you inject dependency?

Types of Dependency Injection The injector class injects dependencies broadly in three ways: through a constructor, through a property, or through a method. Constructor Injection: In the constructor injection, the injector supplies the service (dependency) through the client class constructor.

Does dependency injection affect performance?

There is a performance impact, but its effect will depend on many different variables. Every architectural decision involves research and weighing pros and cons, and ultimately boils down to a subjective opinion. SO isn't the right place to ask broad and opinionated questions.


1 Answers

Most ioc containers should support this. For example, with autofac you might do:

// in another assembly
class plugin {
   // take in required services in the constructor
   public plugin(ILogger logger) { ... }
}

var cb = new ContainerBuilder();

// register services which the plugins will depend on
cb.Register(cc => new Logger()).As<ILogger>();

var types = // load types
foreach (var type in types) {
    cb.RegisterType(type); // logger will be injected
}

var container = cb.Build();
// to retrieve instances of the plugin
var plugin = cb.Resolve(pluginType);

Depending on how the rest of your app will call the plugins, you can alter the registrations appropriately (e. g. register with AsImplementedInterfaces() to retrieve the plugin by a known interface or Keyed to retrieve the plugin by some key object (e. g. a string)).

like image 151
ChaseMedallion Avatar answered Oct 06 '22 23:10

ChaseMedallion