I am trying to improve my current installed assemblies that use C # MEF. Since these assemblies are already used in production, changing individual classes directly is NOT a viable approach at the moment. First of all, I am adding new behavior to existing ones. For example, I have:
public IExtension { Object Execute(); } public BaseExtension : IExtension { // other methods and members public virtual Object Execute() { // do operations here. } } [Export(typeof(IExtension)] public AppRecordExtension : BaseExtension { // .. other methods and members public override Object Execute() { base.Execute(); // shown just for example.. this.someOperation(); } } // other extensions made.
Now the above works when the MEF container calls the extension in the driver:
[ImportMany(typeof(IExtension)] private IEnumerable<Lazy<IExtension>> operations; public void ExecuteExtensions() { var catalog = new AggregateCatalog( new AssemblyCatalog(Assembly.GetExecutingAssembly()), new DirectoryCatalog("extensions", ".dll")); CompositionContainer container = new CompositionContainer(catalog); container.ComposeParts(this); Dictionary<IExtension, object> result = new Dictionary<IExtension, object>(); foreach(Lazy(IExtension> extension in operations) { result.Add((extension.Value, extension.Value.Execute()); } }
However, if I want to implement specific decorators for IExtension or BaseExtension, I don’t understand where I should put them in the container, or how I should put attributes on decorators so that all IExtension source classes load and execute with additional behavior. IExtension decorator example:
// do I put an attribute here? // if an attribute is put here, how does the MEF container call it? public BatchableExtension : BaseExtension { private IExtension extension = null; public BatchableExtension( IExtension extension) { this.extension = extension; } public override Object Execute() { this.extension.Execute(); doSomeBatchSpecificOperation(); } } // do I put an attribute here? // if an attribute is put here, how does the MEF container call it? public MonitoringExtension : BaseExtension { private IExtension extension = null; public MonitoringExtension( IExtension extension) { this.extension = extension; } public override Object Execute() { this.extension.Execute(); doSomeMonitoringSpecificOperation(); doSomeMoreBehaviors(); }
Can anyone help here? I want to make sure that when the container raises extensions, the new behavior is also selected, depending on the parameters passed (for example, if isBatchable = true, adds BatchableExtension, etc.). If it were a non-MEF, the above would look something like this:
public void Main(String[] args) { IExtension ext = new AppRecordExtension(); // this is the part where I want to simulate when I use MEF. IExtension ext2 = new MonitoringExtension(new BatchableExtension(ext)); ext2.Execute(); }