在不同appdomain

时间:2015-05-15 11:21:37

标签: c# .net serialization .net-assembly appdomain

任务

  • 在运行时加载和/或卸载外部程序集。
  • 在外部程序集中执行代码,将变量传递给外部代码并期望返回值。

Problem

  

如果不卸载包含它的所有应用程序域,就无法卸载单个程序集。使用AppDomain中的卸载方法卸载应用程序域。

解决方案

创建一个新的AppDomain,将外部程序集加载到新的AppDomain中并执行您需要在外部程序集中执行的任何代码,并且(可选)销毁新的AppDomain之后。

问题2

不幸的是,这个过程并不简单,并且要求您使用中间代理对象,该对象可以调用远程AppDomain中的方法,而无需以任何方式引用本地应用程序域中的对象(这会再次将程序集锁定到本地AppDomain)。

解决方案2

创建一个派生自MarshalByRefObject程序集代理(或包装器),以便CLR可以通过AppDomain边界的引用对其进行封送。

我找到了this代码来完成我需要做的事情,但是......

因此我现在来找你 StackOverflow 寻求帮助,因为我似乎无法弄清楚出了什么问题,为什么以及如何解决它。

现在相信我,在新的AppDomain中加载外部程序集工作正常,但外部程序集中的代码调用不是。

以下是我调用外部程序集的一些代码

public class SOAPWebServiceInvoker
{
    private readonly Guid _assemblyId;
    private readonly IAssemblyManager _assemblyManager;
    private readonly Foo _foo;

    public SOAPWebServiceInvoker(IAssemblyManager assemblyManager, Guid assemblyId, string url)
    {
        _assemblyManager = assemblyManager;
        _assemblyId = assemblyId;
        _foo = new Foo { Url = url };
    }

    public object Invoke(string className, string methodName, Dictionary<string, object> methodParameters)
    {
        return _assemblyManager.Reflect(_assemblyId, assembly => _foo.Invoke(assembly, className, methodName, methodParameters));
    }
}

以前Foo中的代码位于SOAPWebServiceInvoker类中,但我有一个例外:Type 'SOAPWebServiceInvoker' in assembly '...' is not marked as serializable,所以我搬进了一个单独的类,看看是否修复了问题(因为Foo应为Serializable)。

[Serializable]
public class Foo
{
    public string Url { get; set; }

    public object Invoke(Assembly assembly, string className, string methodName, Dictionary<string, object> methodParameters)
    {
        var type = GetTypeInAssembly(assembly, Url, className);
        var method = GetMethodOfType(type, Url, className, methodName);
        var parameters = method.GetParameters();

        if (method.DeclaringType == null) throw new Exception("DecleringType was null for methodInfo.");

        var instance = Activator.CreateInstance(method.DeclaringType);
        return method.Invoke(instance, methodParameters.Select(x =>
        {
            var parameterType = parameters.Single(y => y.Name.Equals(x.Key)).ParameterType;
            if (parameterType.IsEnum)
            {
                return Enum.Parse(parameterType, x.Value.ToString());
            }
            return Convert.ChangeType(x.Value, parameterType);
        }).ToArray());
    }

    private Type GetTypeInAssembly(Assembly assembly, string url, string className) {...}        
    private MethodInfo GetMethodOfType(Type type, string url, string className, string methodName) {...}
}

但我仍然收到序列化异常(但对于Foo): Type 'Foo' in assembly '...' is not marked as serializable

这可能只是一个我忽略的愚蠢的错误,但我不知道我的生活是什么,以及为什么这不会起作用......:S

0 个答案:

没有答案