gpt4 book ai didi

wpf - 缓存 MEF 组件

转载 作者:行者123 更新时间:2023-12-04 15:54:52 26 4
gpt4 key购买 nike

有没有办法缓存每个应用程序启动 (WPF) 的 MEF 组件图,就像 MAF 所做的那样,以避免在每次应用程序启动时发现目录并构建组件图。为了加快我的应用程序启动。
MAF 使用 AddinsStore 存储所有插件,当新插件发现 Store 重建并再次保存时。使用 MEF 设计的模块化应用程序可以做到这一点吗?

编辑:

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

最佳答案

我不知道这是否会对你有 100% 的帮助,但是通过这段代码,我可以控制我的模块的加载顺序。

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

关键是这个附加属性的使用:[ExportMetadata("Order", 1)]
然后你的插件应该是这样的:

 [Export(typeof(YourContract))]
[ExportMetadata("Order", 1)]
public class YourPlugin: YourContract{}

要以正确的顺序加载内容,您将需要以下内容:

接口(interface):
public interface IOrderMetadata {
[DefaultValue(int.MaxValue)]
int Order {
get;
}
}

适配集合:
 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)) {
}
}

用法
[ImportMany(typeof(YourContract), AllowRecomposition = true)] 
internal OrderingCollection<YourContract, IOrderMetadata> Plugins{
get; private set;
}

在您的构造函数中:
this.Plugins= new OrderingCollection<ITemplateMapper, IOrderMetadata>(
lazyRule => lazyRule.Metadata.Order);

我的加载代码(可能与您的不同):
private void LoadModules() {
var aggregateCatalog = new AggregateCatalog();
aggregateCatalog.Catalogs.Add(new DirectoryCatalog(".", "*.Plugin.*.dll"));
var container = new CompositionContainer(aggregateCatalog);
container.ComposeParts(this);
}

我希望这可以帮助您摆脱 MAF

关于wpf - 缓存 MEF 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38185680/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com