我正在尝试从sharepoint URL加载UserControl,但是我没有在GAC中引用程序集。相反,我使用Assembly.Load(byte [])将其内容从数据库加载到当前的AppDomain中。我还添加了AssemblyResolver事件,该事件返回我加载的dll,因此它可以获得正确的上下文。 代码对普通库dll正常工作。 当我尝试加载UserControl时,如果只有主DLL处于GAC中,或者System.CodeDom.Compiler.CodeDomProvider.TryGetProbableCoreAssemblyFilePath(CompilerParameters参数为空,则为空引用),则会出现“无法加载程序集或其中一个引用”错误当两个dll都来自数据库,而ascx处于共享点布局时,则为String&coreAssemblyFilePath。
我要实现的目标是在运行时使用动态加载的程序集或在sharepoint GAC中仅使用主程序集以及从反射引用的控件中加载ascx控件。
这是我的代码: 将程序集加载到appdomain。
if (files.Query.Load())
{
if (_filesFullNameId.ContainsKey(files.Current.FullName))
return result;
Assembly.Load(files.Current.Content);
result.Add(new KeyValuePair<string, int>(files.Current.FullName, fileId));
}
在单例缓存构造函数中向当前应用域添加了Resolver事件:
private Assembly AssemblyResolver(object sender, ResolveEventArgs args)
{
var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name);
if (assembly == null && args.RequestingAssembly != null)
{
LoggingProvider.Logger.WriteToEventLog(new WriteToSystemLogParams
{
//log
});
}
return assembly;
}
然后在共享点服务上执行LoadControl:
SPSecurity.RunWithElevatedPrivileges(
() =>
{
PluginAssemblyCache.Instance.LoadPackageById(MainContext.Instance.GetCurrentDbInfo(), packageId);
var control = page.LoadControl(url);
if (control != null)
{
var type = control.GetType().BaseType;
metadata.SpTypeName = type.FullName;
metadata.AssemblyName = type.Assembly.FullName;
}
});