注册使用MEF和autofac导出的所有模块

时间:2015-09-02 12:04:51

标签: dependency-injection autofac mef

使用Autofac.Mef扩展我想注册导出的模块。有办法吗?

导出

[Export(typeof(IModule))]
public class MyModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<SampleJob>().AsSelf();
    }
}  

注册

var catalog = new DirectoryCatalog(".");
builder.RegisterComposablePartCatalog(catalog); //This would register all exported types.
builder.RegisterModule(//All IModules registerd as that type I want to register as Modules)

1 个答案:

答案 0 :(得分:3)

关于Unleashing modules – part 2中的一种方法,有一篇非常好的文章。方法是使用委托作为工厂来创建模块,而不是导出IModule类型。

using Autofac;

/// <summary>
/// Creates an <see cref="IModule" /> that's responsible for loading
/// dependencies in the specified context.
/// </summary>
/// <param name="mode">The mode the application is running in, let's the implementor
/// of the factory load different dependenices for different modes.</param>
/// <returns>An <see cref="IModule" />.</returns>
public delegate IModule ModuleFactory(ApplicationMode mode);


/// <summary>
/// Describes different modes an application can run in.
/// </summary>
public enum ApplicationMode
{
    /// <summary>
    /// The application is running in a test environment.
    /// </summary>
    Test = 0,

    /// <summary>
    /// The application is running in a staging environment.
    /// </summary>
    Staging = 1,

    /// <summary>
    /// The application is running in production environment.
    /// </summary>
    Production = 2
}

真正的魔力发生在ComposedModule

using Autofac.Builder;
using Autofac;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Collections.Generic;
using System;


/// <summary>
/// An <see cref="Autofac.Builder.Module" /> is composed by with the help of
/// the System.ComponentModel.Composition (MEF) framework.
/// </summary>
public class ComposedModule
    : global::Autofac.Builder.Module
{
    #region Fields
    private ApplicationMode mode;
    private ComposablePartCatalog catalog;
    [Import(typeof(ModuleFactory))]
    private IEnumerable<ModuleFactory> RegisteredModuleFactories; 
    #endregion

    #region Construction
    /// <summary>
    /// Creates a new ComposedModule using the specified catalog to
    /// import ModuleFactory-instances.
    /// </summary>
    /// <param name="mode">The mode the application is running in.</param>
    /// <param name="catalog">The catalog used to import ModuleFactory-instances.</param>
    public ComposedModule(ApplicationMode mode, ComposablePartCatalog catalog)
    {
        if (catalog == null) throw new ArgumentNullException("catalog");

        this.mode = mode;
        this.catalog = catalog;

        this.ImportFactories();
    }

    /// <summary>
    /// Creates a new ComposedModule that loads all the ModuleFactories
    /// exported in assemblies that exists in the directory specified in 
    /// the <param name="modulesDirectoryPath" />-parameter.
    /// </summary>
    /// <param name="mode">The mode the application is running in.</param>
    /// <param name="catalog">The catalog used to import ModuleFactory-instances.</param>
    public ComposedModule(ApplicationMode mode, string modulesDirectoryPath)
        : this(mode, new DirectoryCatalog(modulesDirectoryPath)) { } 
    #endregion

    #region Methods
    private void ImportFactories()
    {
        var batch = new CompositionBatch();
        batch.AddPart(this);

        var container = new CompositionContainer(this.catalog);
        container.Compose(batch);
    }

    protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);

        foreach (var factory in this.RegisteredModuleFactories)
        {
            var module = factory(this.mode);
            builder.RegisterModule(module);
        }
    } 
    #endregion
}

用法

public class MyModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);

        builder.RegisterType<SampleJob>().AsSelf();
    }

    [Export(typeof(ModuleFactory))]
    public static ModuleFactory Factory = x => new MyModule();
}

有关详细信息,请参阅帖子。

此外,您可能想查看以下链接:

http://buksbaum.us/2009/12/06/bootstrapping-an-application-with-mef-and-autofac/ http://kalcik.net/2014/02/09/cooperation-between-the-autofac-and-the-microsoft-extensibility-framework/