C# 正在将程序集加载到WindowsAzure WorkerRole中的单独AppDomain中

C# 正在将程序集加载到WindowsAzure WorkerRole中的单独AppDomain中,c#,reflection,azure,azure-worker-roles,C#,Reflection,Azure,Azure Worker Roles,我正在开发一个Azure Worker角色,该角色需要根据从WCF服务提取的工作定期执行操作。由于Azure部署的性质,我们决定在Azure中实施插件框架,以允许快速更新我们的产品,同时通过消除对完整Azure部署的需要以及支持各种程序集的多个版本来最小化停机时间 插件从云存储下载并加载到包含加载程序集所需的所有相关信息的类中。(请参阅下面的pluginasemblyinfo) 在其他开发工作中,我开发了下面的ReflectionHelper类。这个类可以在其他应用程序中工作,我已经验证了它可以

我正在开发一个Azure Worker角色,该角色需要根据从WCF服务提取的工作定期执行操作。由于Azure部署的性质,我们决定在Azure中实施插件框架,以允许快速更新我们的产品,同时通过消除对完整Azure部署的需要以及支持各种程序集的多个版本来最小化停机时间

插件从云存储下载并加载到包含加载程序集所需的所有相关信息的类中。(请参阅下面的pluginasemblyinfo)

在其他开发工作中,我开发了下面的ReflectionHelper类。这个类可以在其他应用程序中工作,我已经验证了它可以在控制台应用程序中工作

但是,在Azure emulator中运行时,我遇到以下错误:(我在引发异常的行上添加了注释。)

ReflectionHelper类作为源文件添加到调用它的同一程序集。(出于匿名原因,我确实编辑了程序集/名称空间的名称)

鉴于这个类在其他情况下也能工作,我唯一的猜测是这可能是一个信任问题,但我在网上没有找到太多与此相关的信息。任何帮助都将不胜感激

这是ReflectionHelper类的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Serialization;
using System.Web;

namespace MyCompanyName
{
    [Serializable]
    public class ReflectionHelper
    {

        public AppDomain appDomain { get; set; }
        public byte[] PluginBytes { get; set; }
        public string PluginClassName { get; set; }
        public string PluginAssemblyName { get; set; }
        public Dictionary<string, byte[]> AssemblyArchive { get; set; }

        public object GetInstance(AppDomain NewDomain, byte[] PluginBytes, string PluginClassName, string PluginAssemblyName, Dictionary<string, byte[]> AssemblyArchive)
        {
            try
            {
                this.appDomain = NewDomain;
                this.PluginBytes = PluginBytes;
                this.PluginClassName = PluginClassName;
                this.AssemblyArchive = AssemblyArchive;
                this.PluginAssemblyName = PluginAssemblyName;

                //this is the line that throws the serializationexception
                appDomain.AssemblyResolve += new ResolveEventHandler((sender, args) =>
                {
                    AssemblyName x = new AssemblyName(args.Name);
                    string Name = x.Name;
                    if (System.IO.Path.GetExtension(x.Name) != ".dll")
                        Name += ".dll";
                    Assembly Ret = appDomain.Load(this.AssemblyArchive[Name]);

                    return Ret;
                });
                appDomain.DoCallBack(LoaderCallBack);
                return appDomain.GetData("Plugin");
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public void LoaderCallBack()
        {
            ObjectHandle PluginObject = appDomain.CreateInstance(string.Format(this.PluginAssemblyName), PluginClassName);
            appDomain.SetData("Plugin", PluginObject.Unwrap());
        }
    }


}
这是从云存储下载插件时填充的程序集信息类

public class PluginAssemblyInfo
{
    public string ClassName { get; set; }
    public byte[] PluginBytes { get; set; }
    public Dictionary<string, byte[]> AssemblyArchive { get; set; }
    public string AssemblyName { get; set; }
    public DateTime LoadDate { get; set; }
}
公共类pluginasemblyinfo
{
公共字符串类名{get;set;}
公共字节[]PluginBytes{get;set;}
公共字典汇编存档{get;set;}
公共字符串AssemblyName{get;set;}
公共日期时间加载日期{get;set;}
}

该问题似乎与未在子域上设置RelativeSearchPath有关。确保子域具有相同的安装凭据似乎可以解决此问题

AppDomain currentDomain = AppDomain.CurrentDomain;
AppDomain BrokerJobDomain = AppDomain.CreateDomain("WorkerPluginDomain" + Guid.NewGuid().ToString(), null,  AppDomain.CurrentDomain.SetupInformation );

你是在Azure中运行时出现异常,还是仅在模拟器中出现异常?此时我仅在模拟器中尝试过。如果有帮助,在WebRole中尝试执行相同逻辑时也会出现问题。我相信我已经找到了答案。肯特,那么你最终做了什么来解决这个问题呢?
public class PluginAssemblyInfo
{
    public string ClassName { get; set; }
    public byte[] PluginBytes { get; set; }
    public Dictionary<string, byte[]> AssemblyArchive { get; set; }
    public string AssemblyName { get; set; }
    public DateTime LoadDate { get; set; }
}
AppDomain currentDomain = AppDomain.CurrentDomain;
AppDomain BrokerJobDomain = AppDomain.CreateDomain("WorkerPluginDomain" + Guid.NewGuid().ToString(), null,  AppDomain.CurrentDomain.SetupInformation );