gpt4 book ai didi

.net - 将程序集加载到另一个 AppDomain 和类型检查

转载 作者:行者123 更新时间:2023-12-01 05:26:23 26 4
gpt4 key购买 nike

我正在尝试将程序集加载到另一个 appdomain 中(以便在不需要时能够卸载它们),但我也希望能够检查加载的程序集中的类型并创建我的类型的实例(通过 Activator)。此外,我不希望程序集在加载时被锁定。

我不明白这怎么可能。我尝试过的事情:

  • Loading Assembly.Load(File.ReadAllBytes(path)) 帮助我加载程序集而不锁定它,因此它可以被删除/移动。这会将程序集加载到当前的 appdomain 中,因此无法卸载它。
  • 创建另一个 AppDomain 并使用 AppDomain.Load() 将程序集加载到新的 AppDomain 中,但无法检查加载的 AppDomain 中的所有类型。除非我知道类型完全限定的类型名称,否则我无法创建任何东西,即使那样它们也必须是可序列化的或从 MarshallByRef 派生的。另一个 AppDomain 的东西只能通过代理工作,所以如果没有契约(Contract)/共享接口(interface)等,就很难创建东西。
  • MEF 还将程序集加载到当前的 AppDomain 中,因此它基本上是在做同样的事情。
  • Mono.Cecil 允许对加载的程序集进行类型检查,但是我无法使用 TypeReference 创建类型。也许如果有办法将 TypeReference 转换为 Type?

  • 我检查了 ILSpy 是如何做到这一点的,毫不奇怪,它使用 Mono.Cecil 加载/卸载程序集,但话又说回来,它不会创建任何类型的实例,只是进行可能通过 Mono.Cecil 进行的类型检查路线。

    现在的问题是,这甚至可能吗?我错过了什么吗?

    最佳答案

    如果您将程序集加载到另一个应用程序域,那么您当然应该在那里创建实例并在那里使用它们。除此之外,不确定您遇到了什么问题。

    更新

  • 添加代码以从列表中选择类型
  • 更改为仅将类型名称作为字符串跨域传递

  • using System;
    using System.IO;
    using System.Reflection;
    using System.Runtime.Remoting;

    public class MainClass : MarshalByRefObject
    {
    static void Main(string[] args)
    {
    if (args.Length == 0)
    {
    Console.WriteLine("usage: {0} assembly", Path.GetFileName(Assembly.GetExecutingAssembly().Location));
    return;
    }
    AppDomain other = AppDomain.CreateDomain("other");
    Type myType = typeof(MainClass);
    // create a loader instance in the new domain
    MainClass loader = (MainClass)other.CreateInstanceAndUnwrap(myType.Assembly.FullName, myType.FullName);
    string assemblyName;
    string[] types = loader.LoadAssembly(args[0], out assemblyName);
    Console.WriteLine("Loaded assembly {0}.", assemblyName);
    Console.WriteLine("Types:");
    for(int i = 0; i < types.Length; i += 1)
    {
    Console.WriteLine("[{0}] {1}", i, types[i]);
    }
    Console.Write("Enter index of type to create, -1 to exit: ");
    int create = Int32.Parse(Console.ReadLine());
    if (create < 0)
    {
    return;
    }
    Console.WriteLine("Creating instance of type {0}", types[create]);
    Console.WriteLine("Type of the created instance was: {0}", loader.CreateInstance(assemblyName, types[create]));
    }

    string[] LoadAssembly(string path, out string assemblyName)
    {
    Console.WriteLine("LoadAssembly executing in appdomain {0}", AppDomain.CurrentDomain.FriendlyName);
    Assembly assembly = Assembly.Load(File.ReadAllBytes(path));
    assemblyName = assembly.FullName;
    return Array.ConvertAll<Type, string>(assembly.GetExportedTypes(), x => x.FullName);
    }

    string CreateInstance(string assemblyName, string typeName)
    {
    Console.WriteLine("CreateInstance executing in appdomain {0}", AppDomain.CurrentDomain.FriendlyName);
    object instance = Activator.CreateInstance(assemblyName, typeName).Unwrap();
    // do something useful with the instance here
    return instance.GetType().FullName;
    }

    public override object InitializeLifetimeService()
    {
    return null;
    }
    }
    log4net.dll 的示例输出:
    $ mono main.exe log4net.dll
    LoadAssembly executing in appdomain other
    Loaded assembly log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=a5715cc6d5c3540b.
    Types:
    [0] log4net.Core.SecurityContext
    [1] log4net.Core.LoggerWrapperImpl
    [2] log4net.Core.LogImpl
    [3] log4net.Core.DefaultRepositorySelector
    ...
    [160] log4net.Appender.AspNetTraceAppender
    [161] log4net.Appender.FileAppender
    ...
    [197] log4net.Repository.LoggerRepositoryConfigurationResetEventHandler
    [198] log4net.Repository.LoggerRepositoryConfigurationChangedEventHandler
    Enter index of type to create, -1 to exit: 161
    Creating instance of type log4net.Appender.FileAppender
    CreateInstance executing in appdomain other
    Type of the created instance was: log4net.Appender.FileAppender

    关于.net - 将程序集加载到另一个 AppDomain 和类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13638493/

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