Je ne sais pas si cela vous aidera à 100%, mais avec ce code, je contrôle l'ordre de chargement de mes modules.
Si vous pouvez contrôler votre charge commande, vous pourriez être en mesure de mettre tous vos années * .Dll dans le même dossier et gagner du temps, les trouvant dans les sous-dossiers:
La clé est l'utilisation de cet attribut supplémentaire: [ExportMetadata("Order", 1)]
Ensuite, votre plug-in devrait ressembler à ceci:
[Export(typeof(YourContract))]
[ExportMetadata("Order", 1)]
public class YourPlugin: YourContract{}
Pour faire avancer les choses Loaded dans l'ordre, vous aurez besoin de quelque chose comme ceci:
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 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)) {
}
}
Utilisation
[ImportMany(typeof(YourContract), AllowRecomposition = true)]
internal OrderingCollection<YourContract, IOrderMetadata> Plugins{
get; private set;
}
Dans votre Constructor:
this.Plugins= new OrderingCollection<ITemplateMapper, IOrderMetadata>(
lazyRule => lazyRule.Metadata.Order);
Mon chargement code (peut être différent du vôtre):
private void LoadModules() {
var aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(new DirectoryCatalog(".", "*.Plugin.*.dll"));
var container = new CompositionContainer(aggregateCatalog);
container.ComposeParts(this);
}
J'espère que cela pourrait vous aider à vous débarrasser du CRG
Je ne comprends vraiment pas cette question ... Je n'ai jamais fait de MAF auparavant, mais beaucoup de MEF.Pourquoi ne pas simplement déplacer tous les composants MEF dans le même dossier et le charger directement à partir de là? Après avoir lu [this] (http://stackoverflow.com/questions/835182/choosing-between-mef-and-maf-system-addin), MAF semble être une façon compliquée et inutile de faire avancer les choses – lokusking
Non je ne peux pas déplacez tous les assemblages dans un répertoire. J'utilise des catalogues d'annuaire et j'ai la structure qui coule: (extensions, modules, services gérés, SDK) dossiers, l'ordre de chargement important. –
Vous pouvez également définir l'ordre de chargement dans Mef. Cela nécessite un peu de code moche, mais ça fonctionne. Si cela vous intéresse, faites le moi savoir et je posterai une réponse – lokusking