wpf - Caching MEF Components -
is there way cache mef components graph per-application startup (wpf), maf avoid discovering directories , constructing components graph every application startup. in order speed application startup. maf uses addinsstore store addins, when new addin discovred store rebuilt , saved again. possible modular application designed mef?
edit:
in project architecture have extension, modules , managed services have different exports like(iextension, imodule, imanagedservice), , handling start dependencies of components, want precisely ex(the extensions directory) contains many dlls , may not dlls contains (exports/imports) because of dlls references extensions. default discovering behavior of mef searching exports/imports in assemblies in extension directory, want modify behavior looking @ first time dlls , catch types , names , dlls use them in next startup time. catch directly load components(exports) mef know available components , places without loading , searching dlls. seems dictionary of exports , places , dependencies instance directly places(dll).
i dont know if 100%, code, im controlling load-order of modules.
if can control load-order, might able put *.dll's in same folder , save time, finding them in subfolders:
the key usage of additional attribute: [exportmetadata("order", 1)]
then plugin should :
[export(typeof(yourcontract))] [exportmetadata("order", 1)] public class yourplugin: yourcontract{}
to things loaded in right order, need this:
interface:
public interface iordermetadata { [defaultvalue(int.maxvalue)] int order { get; } }
adaptingcollection:
public class adaptingcollection<t, m> : icollection<lazy<t, m>>, inotifycollectionchanged { /// <summary> /// constructor</summary> public adaptingcollection() : this(null) { } /// <summary> /// constructor</summary> /// <param name="adaptor">function apply items in collection</param> public adaptingcollection(func<ienumerable<lazy<t, m>>, ienumerable<lazy<t, m>>> adaptor) { this._madaptor = adaptor; } /// <summary> /// collectionchanged event inotifycollectionchanged</summary> public event notifycollectionchangedeventhandler collectionchanged; /// <summary> /// force adaptor function run again</summary> public void reapplyadaptor() { if (this._madapteditems == null) return; this._madapteditems = null; this.oncollectionchanged(new notifycollectionchangedeventargs(notifycollectionchangedaction.reset)); } #region icollection implementation /// <summary> /// returns whether item present in collection</summary> /// <remarks>accessors work directly against adapted collection</remarks> /// <param name="item">item for</param> /// <returns>true if item in collection</returns> public bool contains(lazy<t, m> item) { return this.adapteditems.contains(item); } /// <summary> /// copies entire list one-dimensional array, starting @ specified index of target array</summary> /// <remarks>accessors work directly against adapted collection</remarks> /// <param name="array">the target array</param> /// <param name="arrayindex">the starting index</param> public void copyto(lazy<t, m>[] array, int arrayindex) { this.adapteditems.copyto(array, arrayindex); } /// <summary> /// gets number of items in collection</summary> /// <remarks>accessors work directly against adapted collection</remarks> public int count => this.adapteditems.count; /// <summary> /// gets whether collection read only.</summary> /// <remarks>accessors work directly against adapted collection</remarks> public bool isreadonly => false; /// <summary> /// gets enumerator collection</summary> /// <remarks>accessors work directly against adapted collection</remarks> /// <returns>the ienumerator</returns> public ienumerator<lazy<t, m>> getenumerator() { return this.adapteditems.getenumerator(); } ienumerator ienumerable.getenumerator() { return this.getenumerator(); } /// <summary> /// add item collection</summary> /// <remarks>mutation methods work against complete collection , force /// reset of adapted collection</remarks> /// <param name="item">the item add</param> public void add(lazy<t, m> item) { this._mallitems.add(item); this.reapplyadaptor(); } /// <summary> /// clear items collection</summary> /// <remarks>mutation methods work against complete collection , force /// reset of adapted collection</remarks> public void clear() { this._mallitems.clear(); this.reapplyadaptor(); } /// <summary> /// remove item collection</summary> /// <remarks>mutation methods work against complete collection , force /// reset of adapted collection</remarks> /// <param name="item">the item remove</param> /// <returns>true if item found, otherwise false</returns> public bool remove(lazy<t, m> item) { bool removed = this._mallitems.remove(item); this.reapplyadaptor(); return removed; } #endregion /// <summary> /// invoke adaptor function on collection</summary> /// <param name="collection">the collection adapt</param> /// <returns>the adapted collection</returns> protected virtual ienumerable<lazy<t, m>> adapt(ienumerable<lazy<t, m>> collection) { if (this._madaptor != null) { return this._madaptor.invoke(collection); } return collection; } /// <summary> /// fire collectionchanged event</summary> /// <param name="e">event args</param> protected virtual void oncollectionchanged(notifycollectionchangedeventargs e) { this.collectionchanged?.invoke(this, e); } private list<lazy<t, m>> adapteditems => this._madapteditems ?? (this._madapteditems = this.adapt(this._mallitems).tolist()); private readonly list<lazy<t, m>> _mallitems = new list<lazy<t, m>>(); private readonly func<ienumerable<lazy<t, m>>, ienumerable<lazy<t, m>>> _madaptor; private list<lazy<t, m>> _madapteditems; }
oderingcollection
public class orderingcollection<t, m> : adaptingcollection<t, m> { /// <summary> /// constructor</summary> /// <param name="keyselector">key selector function</param> /// <param name="descending">true sort in descending order</param> public orderingcollection(func<lazy<t, m>, object> keyselector, bool descending = false) : base(e => descending ? e.orderbydescending(keyselector) : e.orderby(keyselector)) { } }
usage
[importmany(typeof(yourcontract), allowrecomposition = true)] internal orderingcollection<yourcontract, iordermetadata> plugins{ get; private set; }
in constructor:
this.plugins= new orderingcollection<itemplatemapper, iordermetadata>( lazyrule => lazyrule.metadata.order);
my loading-code (might differ yours):
private void loadmodules() { var aggregatecatalog = new aggregatecatalog(); aggregatecatalog.catalogs.add(new directorycatalog(".", "*.plugin.*.dll")); var container = new compositioncontainer(aggregatecatalog); container.composeparts(this); }
i hope might rid of maf
Comments
Post a Comment