在Windows 10 UWP(15063)中,我需要在调用程序集中迭代类型以发现使用特定自定义属性装饰的类型.我找不到旧的System.Reflection.Assembly.Current.GetCallingAssembly()方法.这是我提出的替代方案(未经测试的原型):
using System;
using System.Diagnostics;
using System.Reflection;
using System.Linq;
namespace UWPContainerUtility
{
public static class Helpers
{
public static Assembly GetCallingAssembly()
{
var thisAssembly = typeof(Helpers).GetTypeInfo().Assembly;
StackFrame[] frames = GetStackTraceFrames();
var result = frames.Select(GetFrameAssembly)
.FirstOrDefault(NotCurrentAssembly);
return result;
StackFrame[] GetStackTraceFrames()
{
StackTrace trace = null;
try
{
throw new Exception();
}
catch (Exception stacktraceHelper)
{
trace = new StackTrace(stacktraceHelper, true);
}
return trace.GetFrames();
}
Assembly GetFrameAssembly(StackFrame f)
{
return f.GetMethod().DeclaringType.GetTypeInfo().Assembly;
}
bool NotCurrentAssembly(Assembly a)
{
return !ReferenceEquals(thisAssembly, a);
}
}
}
}
除了抛出虚假的例外之外,目前还有其他办法吗?这样做的真正方法是什么?
提前致谢!
*为清晰起见编辑了示例代码
解决方法:
我认为这是最好的方法:
IEnumerable<Assembly> GetCallingAssemblies()
{
var s = new StackTrace();
return s.GetFrames()
.Select(x => x.GetMethod().DeclaringType.GetTypeInfo().Assembly)
.Where(x => !Equals(x, GetType().GetTypeInfo().Assembly))
.Where(x => !x.FullName.StartsWith("Microsoft."))
.Where(x => !x.FullName.StartsWith("System."));
}
Assembly GetCallingAssembly()
{
return GetCallingAssemblies().First();
}
请注意,这不是每个项目的直接解决方案.你需要测试和调整这个,因为微软.和系统.可能不适合您的情况.您可能有更多或更少的程序集要从列表中过滤掉.在过滤掉当前值之后挑选第一个似乎是获取调用程序集的最明显方法,但是根据堆栈的构建方式,也可能需要进行调整.
关键是,有一种方法,这将让你开始.
祝你好运.