使用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)
答案 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/