gpt4 book ai didi

.net - 程序集/目录的延迟加载

转载 作者:行者123 更新时间:2023-12-04 21:20:27 29 4
gpt4 key购买 nike

我的应用程序由几个核心程序集和几个扩展/插件程序集组成。为了让 MEF 知道插件必须提供的所有部件,即使我永远不会使用它们的任何部件,我也必须加载这些程序集。这使得应用程序需要更多时间来启动(如果我要在启动时加载所有程序集)并且还增加了内存占用。

理想情况下,我不必加载程序集,直到我真正需要它们。我只会加载插件的导出数据,当我真正需要导入零件时,MEF 会加载组件并提供零件。

我发现有些东西几乎可以完成我刚写的所有内容,但是在 MEF CachedAssemblyCatalog - Lazy Loading of Assemblies 中询问之后,我意识到这段代码不被认为是稳定的,并且不被 MEF 团队维护,所以我决定不使用它。

我的问题是如何才能实现这种行为:

  • 无需加载整个程序集即可访问插件程序集的导出元数据。
  • 与导入零件的代码透明集成;即像往常一样使用导入 - 其他人(专门的目录?)将在必要时负责加载组件并提供请求的零件。
  • 不会丢失任何现有的 MEF 功能,例如重组、惰性类型等。

  • 我对需要提前解析插件以创建元数据程序集、XML 文件或诸如此类的解决方案完全满意。

    最佳答案

    如果您刚刚延迟加载程序集,那么您可能会使用 this question 的部分解决方案。 .您不需要获取在该解决方案中检索到的所有信息。可能只有契约(Contract)名称、装配名称以及零件是导出还是导入契约(Contract)。然后,您可以编写一个目录,根据需要加载程序集,例如:

    public sealed class DelayLoadingCatalog : ComposablePartCatalog
    {
    // List containing tuples which have the 'contract name'
    // and the 'assembly name'
    private readonly List<Tuple<string, string>> m_Plugins
    = new List<Tuple<string, string>>();
    private readonly Dictionary<string, AssemblyCatalog> m_Catalogs
    = new Dictionary<string, AssemblyCatalog>();

    public DelayLoadingCatalog(IEnumerable<Tuple<string, string>> plugins)
    {
    m_Plugins.AddRange(plugins);
    }

    public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
    {
    var partsToLoad = m_Plugins
    .Where(t => t.Item1.Equals(definition.ContractName));
    foreach (var part in partsToLoad)
    {
    if (!m_Catalogs.ContainsKey(part.Item2.Name))
    {
    var assembly = Assembly.Load(new AssemblyName(part.Item2.Name));
    m_Catalogs.Add(part.Item2.Name, new AssemblyCatalog(assembly));
    }
    }

    return m_Catalogs.SelectMany(p => p.Value.GetExports(definition));
    }

    public override IQueryable<ComposablePartDefinition> Parts
    {
    get
    {
    throw new NotImplementedException();
    }
    }
    }

    然后你可以像这样使用
    class Program
    {
    public void Init()
    {
    var domainSetup = new AppDomainSetup
    {
    ApplicationBase = Directory.GetCurrentDirectory(),
    };

    var scanDomain = AppDomain.CreateDomain(
    "scanDomain",
    null,
    domainSetup);
    var scanner = scanDomain.CreateInstanceAndUnwrap(
    typeof(MyScanner).Assembly.FullName,
    typeof(MyScanner).FullName) as MyScanner;
    var plugins = scanner.Scan(myPluginsPath);

    // Make sure we don't have the assemblies loaded anymore ...
    AppDomain.Unload(scanDomain);

    var catalog = new DelayLoadingCatalog(plugins);
    var container = new CompositionContainer(catalog);

    container.ComposeParts(this);
    }

    [Import("MyCoolExport")]
    public object MyImport
    {
    get;
    set;
    }
    }

    示例 DelayLoadCatalog 不是很聪明,因为它会继续搜索元组列表。不过,优化代码应该不会太难。例如,您可以检查是否所有程序集都已加载并在那时停止搜索该列表。

    关于.net - 程序集/目录的延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12965137/

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