我正在开发一个Azure Worker Role,需要定期执行基于从WCF服务中获取的工作的操作。由于Azure部署的性质,我们决定在Azure中实现插件框架,以允许快速更新产品,并通过删除对完整Azure部署的需求来最小化停机时间,同时支持各种程序集的多个版本。
插件会从云存储中下载并加载到包含加载程序集所需所有相关信息的类中(请参见下面的PluginAssemblyInfo)。
在其他开发工作中,我开发了下面的ReflectionHelper类。这个类在其他应用程序中可以工作,在控制台应用程序中也可以验证它可以工作。
然而,在Azure模拟器中运行时,我遇到了以下错误:(我在引发异常的那一行添加了注释。)
ReflectionHelper类作为源文件添加到调用它的同一个程序集中。(由于隐私原因,我编辑了程序集/命名空间的名称)
鉴于该类在其他情况下有效,我的猜测是可能存在信任问题,但我在网上没有找到太多相关信息。非常感谢您的帮助。
这是ReflectionHelper类的代码。
这是调用它的代码片段。
这是装配信息类,当插件从云存储下载时,该类会被填充。
插件会从云存储中下载并加载到包含加载程序集所需所有相关信息的类中(请参见下面的PluginAssemblyInfo)。
在其他开发工作中,我开发了下面的ReflectionHelper类。这个类在其他应用程序中可以工作,在控制台应用程序中也可以验证它可以工作。
然而,在Azure模拟器中运行时,我遇到了以下错误:(我在引发异常的那一行添加了注释。)
Type is not resolved for member 'MyCompanyName.ReflectionHelper,MyCompanyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
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());
}
}
}
这是调用它的代码片段。
AppDomain currentDomain = AppDomain.CurrentDomain;
AppDomainSetup domainSetup = new AppDomainSetup() { };
AppDomain BrokerJobDomain = AppDomain.CreateDomain("WorkerPluginDomain" + Guid.NewGuid().ToString());//, null, new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase });
ReflectionHelper helper = new ReflectionHelper();
object Instance = helper.GetInstance(BrokerJobDomain, pluginAssembly.PluginBytes, pluginAssembly.ClassName, pluginAssembly.AssemblyName, pluginAssembly.AssemblyArchive);
IWorkPlugin executor = (IWorkPlugin)Instance;
这是装配信息类,当插件从云存储下载时,该类会被填充。
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; }
}