2016-10-12 1 views
0

Je prévois d'utiliser MEF pour implémenter une architecture de plugin pour mes plugins d'import. Ces plugins vont importer diverses données dans la base de données (par exemple, les clients, les adresses, les produits, etc.).Utilisation de MEF avec DI dans une application WebApi

La classe plugin d'import ressemble à ceci:

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() {} 
} 

J'ai alors un contrôleur, qui obtient d'abord tous les plug-ins d'importation comme suit:

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); 
} 

Le module d'importation doit faire référence à mon assemblée Services parce que c'est là que le BL a lieu. J'inscrire mes services dans le principal projet WebAPI avec Autofac comme suit:

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

Est-il possible de passer différents services à différents plug-ins d'importation?

Par exemple, si je l'importation de produits J'ai besoin de passer le ProductService, et si je clients l'importation je pourrais avoir besoin de passer CustomerService et AddressService.

Comment puis-je injecter ces services à l'intérieur des plugins (à travers leurs constructeurs comme on le ferait dans un contrôleur)?

+0

Vous ne pouvez pas enregistrer des modules dans vos plugins? Par exemple, dans ninject vous pouvez spécifier NinjectModule dans lequel vous enregistrez vos dépendances de plugin. Ensuite, dans vos modules principaux, vous inscrivez simplement tous les modules dans le dossier plugin, et toutes les implémentations de vos interfaces BL seront disponibles dans les plugins. – eocron

Répondre

0

Pour l'architecture plugin comme, il faut trois choses:

  • Contrats (assemblage basicaly contenant des interfaces simples uniquement et objets withouth BL). Cela sera utilisé comme API pour vos plugins. En outre, vous pouvez spécifier ici l'interface IImportPlugin.

  • Module chargé de charger des modules d'extension à partir d'un dossier ou d'un autre emplacement.

  • Module dans chaque plugin que vous créez, pour enregistrer votre plugin comme IImportPlugin à l'intérieur du conteneur DI.

Vous pouvez enregistrer vos modules de plug-in comme celui-ci dans la boucle:

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

Dans votre ensemble de plug-in, dans le module spécifique, vous spécifiez uniquement l'enregistrement de votre plugin:

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

Puis, en mise en œuvre de plugin ImportCustomer vous pouvez utiliser tout de contrat assemblée (par exemple e votre ICustomerService interface). Et si votre système a enregistré des dépendances pour votre plugin, il sera chargé avec succès dans le conteneur DI.

+0

Je ne veux pas enregistrer les plugins en DI car ils doivent être connus à l'avance et cela va à l'encontre du but d'une architecture plugin utilisant MEF. –