Autofac 可以组合具有 Mef 依赖项的现有对象吗?
Can Autofac compose existing objects with Mef dependencies?
我正在将基于 mef 的 ServiceLocator 与 Autofac 集成。当前定位器能够通过设置 CompositionBatch 然后在对象上注入依赖项来组合 existing 对象。一个简单的复制:
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();
}
如果您需要做的只是使用 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
class 已注册。)
请记住,这确实意味着 Autofac 需要解析 MyExport
类型 - 因此如果它具有依赖项,则也需要向 Autofac 注册这些依赖项。
我正在将基于 mef 的 ServiceLocator 与 Autofac 集成。当前定位器能够通过设置 CompositionBatch 然后在对象上注入依赖项来组合 existing 对象。一个简单的复制:
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();
}
如果您需要做的只是使用 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
class 已注册。)
请记住,这确实意味着 Autofac 需要解析 MyExport
类型 - 因此如果它具有依赖项,则也需要向 Autofac 注册这些依赖项。