Autofac可以用Mef依赖项组合现有对象吗?

时间:2015-06-23 10:27:24

标签: mef autofac

我正在将基于mef的ServiceLocator与Autofac集成。当前定位器能够通过设置CompositionBatch然后在对象上注入依赖项来组成现有对象。一个简单的复制品:

public void MefCompositionContainer_CanComposeExistingObjects()
{
    //1. Initialize Mef
    var composablePartCatalogs = new List<ComposablePartCatalog>
    {
        new AssemblyCatalog(Assembly.GetExecutingAssembly())
        //A lot more here..
    };

    var aggregateCatalog = new AggregateCatalog(composablePartCatalogs);
    var container = new CompositionContainer(aggregateCatalog, true);
    //2. Mef is able to compose existing object
    var objectWithPropertyImport = new ClassWithPropertyImport();
    Compose(container, objectWithPropertyImport);
    objectWithPropertyImport.ImportOfMefExport.Should().NotBeNull();
}

static T Compose<T>(CompositionContainer container, T value)
{
    var batch = new CompositionBatch();
    batch.AddPart(value);
    container.Compose(batch);
    return value;
}

需要以下课程:

[Export]
public class MefExport { }

//Note that this class does not have the [Export] attribute
public class ClassWithPropertyImport
{
    [Import]
    public MefExport ImportOfMefExport { get; set; }
}

使用Autofac是否可以实现相同的目标?如果是这样 - 应该在这里添加/更改什么来组成objectWithPropertyImport?

public void Autofac_CanComposeExistingObjects()
{
    //1. Initialize Mef
    var composablePartCatalogs = new List<ComposablePartCatalog>
    {
        new AssemblyCatalog(Assembly.GetExecutingAssembly())
        //A lot more here..
    };

    var aggregateCatalog = new AggregateCatalog(composablePartCatalogs);

    //2. Initialize Autofac and setup mef-integration
    var builder = new ContainerBuilder();
    builder.Register(c => new AutofacExport()).Exported(x => x.As<AutofacExport>());
    builder.RegisterComposablePartCatalog(aggregateCatalog);

    var ioc = builder.Build();

    var objectWithPropertyImport = new ClassWithPropertyImport();
    // Now what?

    // Updated according to solution from Travis Illig.
    // The following code works for me:
    ioc.InjectProperties(objectWithPropertyImport);
    objectWithPropertyImport.ImportOfMefExport.Should().NotBeNull();
}

1 个答案:

答案 0 :(得分:0)

如果你需要做的只是使用Autofac注入新对象的属性,那么在生命周期范围/容器上使用InjectProperties方法。

using Autofac;

public class ClassWithPropertyImport
{
    public MyExport ImportedProperty { get; set; }
}

public class MyExport { }

var builder = new ContainerBuilder();
builder.RegisterType<MyExport>();
var container = builder.Build();

using(var scope = container.BeginLifetimeScope())
{
    var c = new ClassWithPropertyImport();
    scope.InjectProperties(c);
    c.ImportedProperty.Should().NotBeNull();
}

只要您注入的类型在Autofac中注册,它就可以正常工作。您不需要注册的东西的类型。 (注意ClassWithPropertyImport未在Autofac中注册,但MyExport类是。)

请记住,它确实意味着Autofac需要解析MyExport类型 - 所以如果它有依赖关系,那么那些也需要在Autofac中注册。