我正在开发一些软件,它将为某些dll动态构建菜单项,以便我们可以根据用户计算机上可用的dll动态加载组件。我想要加载的任何dll都已在AssemblyInfo.cs文件中标记了Assembly属性,以及我如何确定是否要为该dll构建菜单项。到目前为止,这是我的方法:
private void GetReportModules() {
foreach (string fileName in Directory.GetFiles(Directory.GetCurrentDirectory())) {
if (Path.GetExtension(fileName) == ".dll" || Path.GetExtension(fileName) == ".exe") {
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(fileName);
object[] attributes = assembly.GetCustomAttributes(typeof(ReportNameAttribute), false);
if (attributes.Count() > 0) {
ReportNameAttribute reportNameAttribute = attributes[0] as ReportNameAttribute;
Type type = assembly.GetType(reportNameAttribute.BaseType);
MenuItem customReportsMenuItem = new MenuItem();
customReportsMenuItem.Header = reportNameAttribute.ReportName;
ReportsMenuItem.Items.Add(customReportsMenuItem);
customReportsMenuItem.Click += (s, ev) => {
var obj = Activator.CreateInstance(type);
type.InvokeMember("Show", System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.InvokeMethod, null, obj, null);
};
}
}
}
}
在大多数情况下它的工作正常,我正在获得我期待的dll并且正在创建我的菜单项。问题是,为了检查属性,我首先需要使用Reflection加载程序集。当我尝试加载缺少的依赖项时,其他一些本地dll会抛出错误,或者模块应该包含一个程序集清单。有没有办法我可以安全地检查是否可以在我实际执行之前加载程序集? (当我把它写出来时听起来很愚蠢)。关于我遇到的问题的任何想法或如何完成我在这里尝试的更好的建议?感觉有点过头了。
答案 0 :(得分:2)
一种方法是使用try catch块。如果它抛出异常,你就不感兴趣......
编辑:
MSDN清楚地解释了LoadFrom可以抛出的异常类型。在您的情况下看起来很可能是FileLoadException。
我确信在捕获后会有代码继续进行。例如,日志框架。我不希望我的框架捕获异常并使我的可执行文件停止等,我希望它能够扼杀异常。我的应用程序不应该只因为一行日志未命中而失败。
答案 1 :(得分:2)
您可以创建单独的AppDomain,尝试在那里加载程序集,发回结果并卸载AppDomain。这样,您就不会使用任何已加载程序集的“垃圾”更改当前的AppDomain。
答案 2 :(得分:1)
您可以尝试使用Unmanaged Metadata API(http://msdn.microsoft.com/en-us/library/ms404384.aspx)或Common Compiler Infrastructure Metadata API(http://ccimetadata.codeplex.com/)作为简单反思的替代品。