Often, there’s a need to register an object into your dependency container that takes constructor arguments. There are a few ways to accomplish this with MEF.
You’re mileage will vary, but my favorite approach is a bit of a hack that leverages a lesser-known feature of MEF: Property Exports.
public class ComplexObjectExportFactory
{
[Export]
public MyComplexObject ComplexObject
{
get
{
return new MyComplexObject("config.xml");
}
}
}
This "simply works" and doesn't require you to do anything intrusive like sub-classing a dependency or registering named parameters on application start-up. The technique is especially useful if you need to provide any kind of conditional logic based on settings and it can even build upon other MEF registered parts, for example:
internal class ComplexObjectExportFactory
{
private readonly IApplicationSettingsProvider _settings;
private readonly IEventAggregator _eventAggregator;
[ImportingConstructor]
public ComplexObjectExportFactory(
IApplicationSettingsProvider settings,
IEventAggregator eventAggregator)
{
_settings = settings;
_eventAggregatore = eventAggregator;
}
[Export]
public MyComplexObject ComplexObject
{
get
{
string configFile = _settings.GetSetting("ComplexObjectConfigFile");
int timeout = _settings.GetSetting<int>("ComplexObjectTimeoutSeconds");
return new MyComplexObject(_eventAggregator, configFile, timeout);
}
}
}
The only real down-fall to this overall approach is that the ComplexObjectExportFactory will never have any usages, so tools like Resharper will think this is dead-code, but this can be solved with a few well placed #pragmas and some comments. The other reason this feels like a hack, and this is more of an esthetics or stylistic difference, is that this feels like it should be a method (eg, factory.Create()) but MEF treats exported methods very differently.
Despite the awkwardness of this class, I’d prefer this to sub-classing third-party dependencies or bloating the bootstrapper with additional initialization logic. Maybe you think so too?
Happy coding.
0 comments:
Post a Comment