I am integrating a mef-based ServiceLocator with Autofac. The current locator is able to compose an existing object by setting up a CompositionBatch and then injecting dependecies on the object. A simple repro:
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;
}
The following classes are required:
[Export]
public class MefExport { }
//Note that this class does not have the [Export] attribute
public class ClassWithPropertyImport
{
[Import]
public MefExport ImportOfMefExport { get; set; }
}
Is it possible to accomplish the same with Autofac? If so - what should be added / changed here to compose 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();
}
If all you need to do is inject the properties of a new object using Autofac, then use the
InjectProperties
method on the lifetime scope / container.As long as the types you're injecting are registered with Autofac, it should work fine. You don't need the type of the thing you're injecting onto registered. (Note the
ClassWithPropertyImport
is not registered with Autofac but theMyExport
class is.)Keep in mind it does mean Autofac needs to resolve the
MyExport
type - so if it has dependencies, those do need to be registered with Autofac as well.