首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >缓存MEF组件

缓存MEF组件
EN

Stack Overflow用户
提问于 2016-07-04 13:14:17
回答 1查看 737关注 0票数 6

是否有方法缓存MEF组件图每个应用程序启动(WPF),就像MAF做的,以避免发现目录和构造组件图每个应用程序启动。以加速我的应用程序启动。MAF使用AddinsStore来存储所有的加载项,当新的加载项发现商店重建并再次保存时。用MEF设计的模块化应用程序可以做到这一点吗?

编辑:

在我的项目体系结构中,我有扩展、模块和托管服务,所以我有不同的导出,比如(IExtension、IModule、IManagedService),我处理所有组件的启动依赖关系,我想要的正是ex(扩展目录)包含许多dll,而且可能不是所有的dll都包含一个(导出/导入),因为有些dll只是对某些扩展的引用。因此,MEF的默认发现行为是搜索Extension中所有程序集中的导出/导入,但我希望通过第一次查看所有dll并捕获类型及其名称和dll来修改此行为,以便在下次启动时使用它们。从捕获直接加载组件(导出),因此MEF将知道可用组件及其位置,而无需加载和搜索dll。它似乎是导出及其位置和依赖项的字典,可以直接从其位置(Dll)获取实例。

EN

回答 1

Stack Overflow用户

发布于 2016-07-15 05:20:20

我不知道这是否会帮助你100%,但使用这个代码,我控制我的模块的加载顺序。

如果可以控制加载顺序,则可以将所有*. all放在同一个文件夹中,并节省一些时间,在子文件夹中找到它们:

关键是使用这个附加属性:[ExportMetadata("Order", 1)]

那么您的插件应该如下所示:

代码语言:javascript
复制
 [Export(typeof(YourContract))]
  [ExportMetadata("Order", 1)]
  public class YourPlugin: YourContract{}

要按正确的顺序加载东西,您需要如下所示:

接口:

代码语言:javascript
复制
public interface IOrderMetadata {
    [DefaultValue(int.MaxValue)]
    int Order {
      get;
    }
  }

AdaptingCollection:

代码语言:javascript
复制
 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

代码语言:javascript
复制
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)) {
    }
  }

使用

代码语言:javascript
复制
[ImportMany(typeof(YourContract), AllowRecomposition = true)] 
    internal OrderingCollection<YourContract, IOrderMetadata> Plugins{
      get; private set;
    }

在你的建筑中:

代码语言:javascript
复制
this.Plugins= new OrderingCollection<ITemplateMapper, IOrderMetadata>(
                           lazyRule => lazyRule.Metadata.Order);

我的加载代码(可能与您的不同):

代码语言:javascript
复制
private void LoadModules() {
      var aggregateCatalog = new AggregateCatalog();
      aggregateCatalog.Catalogs.Add(new DirectoryCatalog(".", "*.Plugin.*.dll"));
      var container = new CompositionContainer(aggregateCatalog);
      container.ComposeParts(this);     
    }

我希望这能帮你摆脱MAF

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38185680

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档