2016-10-12 4 views
0

Ich plane die Verwendung von MEF, um eine Plugin-Architektur für meine Import-Plugins zu implementieren. Diese Plugins werden verschiedene Daten in die Datenbank importieren (zB Kunden, Adressen, Produkte, etc.).Verwenden von MEF mit DI in einer WebApi-Anwendung

Der Import Plugin-Klasse sieht wie folgt aus:

public interface IImportPlugin 
{ 
    string Name { get; } 
    void Import(); 
} 

[Export(typeof(IImportPlugin))] 
public class ImportCustomers : IImportPlugin 
{ 
    private readonly ICustomerService customerService; 

    public string Name 
    { 
     get { this.GetType().Name; } 
    } 

    public ImportCustomers(ICustomerService _customerService) 
    { 
     customerService = _customerService; 
    } 

    public void Import() {} 
} 

ich dann einen Controller haben, der zuerst alle Import Plugins wird wie folgt dar:

public IHttpActionResult GetImportPlugins() 
{ 
    var catalog = new AggregateCatalog(); 

    catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"))); 

    var directoryCatalog = new DirectoryCatalog(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins")); 
    catalog.Catalogs.Add(directoryCatalog); 

    var container = new CompositionContainer(catalog); 
    container.ComposeParts(); 

    var list = container.GetExportedValues<IImportPlugin>().Select(x => x.Name); 
    return Ok(list); 
} 

Der Import-Plugin benötigt meine Services Assembly verweisen weil hier die BL stattfindet. Ich melde mich meine Dienste im Haupt WebAPI Projekt mit Autofac wie folgt:

builder.RegisterAssemblyTypes(assemblies) 
    .Where(t => t.Name.EndsWith("Service")) 
    .AsImplementedInterfaces() 
    .InstancePerRequest(); 

Ist es möglich, verschiedene Dienste zu verschiedenen Import-Plugins übergeben?

Zum Beispiel, wenn ich Produkte importieren bin ich brauche die ProductService zu passieren, und wenn ich Kunden bin importieren könnte ich CustomerService und AddressService übergeben müssen.

Wie kann ich diese Dienste innerhalb der Plugins (über ihre Konstruktoren, genau wie in einem Controller) injizieren?

+0

Können Sie keine Module in Ihren Plugins registrieren? Zum Beispiel können Sie in Ninject NinjectModule angeben, in dem Sie Ihre Plugin-Dependencies registrieren. Dann registrieren Sie in Ihren Hauptmodulen einfach alle Module im Plugin-Ordner, und alle Ihre BL-Schnittstellen-Implementierungen werden in Plugins verfügbar sein. – eocron

Antwort

0

Für Plugin-ähnliche Architektur, brauchen Sie drei Dinge:

  • Contracts (basicaly Montage nur Schnittstellen und einfache Objekte withouth BL enthält). Dies wird als API für Ihre Plugins verwendet. Hier können Sie auch die Schnittstelle IImportPlugin angeben.

  • Das Modul, das verantwortlich ist, wird Plugin-Module aus einem Ordner oder von woanders laden.

  • Modul in jedem Plugin, das Sie erstellen, um Ihr Plugin als IImportPlugin in DI-Container zu registrieren.

Sie können Ihre Plugin-Module wie dies in Schleife registrieren:

builder.RegisterAssemblyModules(/*plugin 'Assembly' goes here*/); 

In Ihrem Plugin Montage in bestimmten Modul, geben Sie Ihre Plugin-Registrierung:

public class MyPluginModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.Register<ImportCustomers>().As<IImportPlugin>(); 
    } 
} 

dann in Plugin-Implementierung ImportCustomer können Sie alles aus Contract Montage (z. B. e Ihre ICustomerService Schnittstelle). Und wenn Ihr System Abhängigkeiten für Ihr Plugin registriert hat, wird es erfolgreich in den DI-Container geladen.

+0

Ich möchte Plugins nicht mit DI registrieren, weil sie vorher bekannt sein müssen und es den Zweck einer Plugin-Architektur mit MEF vereitelt. –