Ich weiß nicht, ob dies Ihnen um 100% helfen wird, aber mit diesem Code, der die Ladereihenfolge meiner Module steuert.
Wenn Sie Ihre Last Ordnung steuern können, können Sie in der Lage sein, alle im selben Ordner, um Ihre * .dll zu setzen und etwas Zeit zu sparen, so dass sie in Unterordner zu finden:
Der Schlüssel dazu ist die Verwendung von dieses zusätzliche Attribut: [ExportMetadata("Order", 1)]
Dann wird Ihr Plugin sollte wie folgt aussehen:
[Export(typeof(YourContract))]
[ExportMetadata("Order", 1)]
public class YourPlugin: YourContract{}
Dinge in der richtigen Reihenfolge geladen zu bekommen, werden Sie so etwas wie dieses benötigen:
Schnittstelle:
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 to apply to items in the collection</param>
public AdaptingCollection(Func<IEnumerable<Lazy<T, M>>, IEnumerable<Lazy<T, M>>> adaptor) {
this._mAdaptor = adaptor;
}
/// <summary>
/// CollectionChanged event for INotifyCollectionChanged</summary>
public event NotifyCollectionChangedEventHandler CollectionChanged;
/// <summary>
/// Force the adaptor function to be 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 the item is present in the collection</summary>
/// <remarks>Accessors work directly against adapted collection</remarks>
/// <param name="item">Item to look for</param>
/// <returns>True if the item is in the collection</returns>
public bool Contains(Lazy<T, M> item) {
return this.AdaptedItems.Contains(item);
}
/// <summary>
/// Copies the entire list to a one-dimensional array, starting at the specified index of the 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 the number of items in the collection</summary>
/// <remarks>Accessors work directly against adapted collection</remarks>
public int Count => this.AdaptedItems.Count;
/// <summary>
/// Gets whether the collection is read only.</summary>
/// <remarks>Accessors work directly against adapted collection</remarks>
public bool IsReadOnly => false;
/// <summary>
/// Gets an enumerator for the 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 an item to the collection</summary>
/// <remarks>Mutation methods work against complete collection and then force
/// a reset of the adapted collection</remarks>
/// <param name="item">The item to add</param>
public void Add(Lazy<T, M> item) {
this._mAllItems.Add(item);
this.ReapplyAdaptor();
}
/// <summary>
/// Clear all items from the collection</summary>
/// <remarks>Mutation methods work against complete collection and then force
/// a reset of the adapted collection</remarks>
public void Clear() {
this._mAllItems.Clear();
this.ReapplyAdaptor();
}
/// <summary>
/// Remove an item from the collection</summary>
/// <remarks>Mutation methods work against complete collection and then force
/// a reset of the adapted collection</remarks>
/// <param name="item">The item to remove</param>
/// <returns>True if the item was found, otherwise false</returns>
public bool Remove(Lazy<T, M> item) {
bool removed = this._mAllItems.Remove(item);
this.ReapplyAdaptor();
return removed;
}
#endregion
/// <summary>
/// Invoke the adaptor function on the collection</summary>
/// <param name="collection">The collection to 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 the 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 to 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)) {
}
}
Nutzungs
[ImportMany(typeof(YourContract), AllowRecomposition = true)]
internal OrderingCollection<YourContract, IOrderMetadata> Plugins{
get; private set;
}
In Ihrem Constructor:
this.Plugins= new OrderingCollection<ITemplateMapper, IOrderMetadata>(
lazyRule => lazyRule.Metadata.Order);
Mein Laden-Code (kann von Ihnen unterscheiden):
private void LoadModules() {
var aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(new DirectoryCatalog(".", "*.Plugin.*.dll"));
var container = new CompositionContainer(aggregateCatalog);
container.ComposeParts(this);
}
mir diese Hoffnung können Sie von MAF Hilfe bekommen zu befreien
Ich verstehe diese Frage nicht ... Ich habe noch nie MAF gemacht, aber viel MEF.Warum verschiebst du einfach alle MEF-Komponenten in den gleichen Ordner und lädst sie direkt von dort? Nach dem Lesen von [this] (http://stackoverflow.com/questions/835182/choosing-between-mef-and-maf-system-addin), scheint MAF wie eine unnötige komplizierte Möglichkeit, Dinge zu erledigen – lokusking
Nein, ich kann nicht Verschiebe alle Assemblies in ein Verzeichnis. Ich benutze Verzeichniskataloge und ich habe die fließende Struktur: (Erweiterungen, Module, Managed Services, SDK) Ordner, der Ladeauftrag wichtig. –
Sie können die Load-Order auch in Mef einstellen. Es erfordert etwas hässlichen Code, aber es funktioniert. Wenn Sie daran interessiert sind, wie zu, lassen Sie es mich wissen, und ich werde eine Antwort posten – lokusking