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