我想使用反射在 GAC 中动态加载程序集的最新安装版本。
到目前为止,我已经找到了多种工作方法来实现这一点,但它们都有其特定的缺点。
最简单的解决方案是使用该Assembly.LoadWithPartialName()方法。但此方法自 .NET Framework 2 起已过时:
var assembly = Assembly.LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime");
Run Code Online (Sandbox Code Playgroud)
另一种可能性是使用Assembly.Load()(如过时警告所推荐的)并在 try/catch 块中使用其完全限定的程序集名称调用不同的程序集版本以获取最新安装的版本。这是维护的尖叫声,看起来很脏:
Assembly assembly = null;
try
{
assembly = Assembly.Load("Microsoft.WindowsAzure.ServiceRuntime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
}
catch (FileNotFoundException) { }
try
{
assembly = Assembly.Load("Microsoft.WindowsAzure.ServiceRuntime, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
}
catch (FileNotFoundException) { }
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要的是,我在 SO 上找到了另一个解决方案,使用该 Assembly.LoadFrom()方法,然后基本上导入程序集管理器模块fusion.dll以找出最新版本的路径。对于这样一个“简单”的任务来说,这似乎太过分了。
如果不使用过时的方法、使用魔法字符串创建维护地狱或通过调用非托管代码,就没有更好的解决方案来实现这一目标吗?
提前致谢!
我正在使用目标框架 - 3.5 在 Visual Studio 2010 中开发一个 Web 应用程序,我正在使用一个 dll(由另一个团队开发),其中我收到以下代码的错误:
string strName = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
Run Code Online (Sandbox Code Playgroud)
我检查并发现 System.Reflection.Assembly.GetEntryAssembly() 返回 null,并搜索了相关内容,并在 msdn 上发现 GetEntryAssembly() 在从任何非托管代码调用时可能返回 null。
当我从我的Web应用程序调用时,它返回null,当我从任何Windows应用程序调用时,它工作正常,即它获取入口程序集名称(开始执行的程序集)。为什么Web应用程序返回null?我不明白。我还尝试从 Visual Studio 中的项目属性将 Web 项目的输出类型更改为类库,但输出类型的下拉列表被禁用,我无法更改项目的输出类型。如果这个问题有任何解决方案,请帮助我。
提前致谢
阿米特·沙哈尼
在下面的代码中, 的类型domainObject有所不同(但以 结尾DO,然后我修剪它以获得相应的表名)。有了表的名称和它的类型,我想tableName用来自domainObject. 因此,我必须首先在表中找到相同的 POCOID来覆盖它。这是到目前为止的代码:
public void Update(object domainObject)
{
Type type = domainObject.GetType();
string tableName = type.Name.Substring(0, type.Name.Length - 2);
PropertyInfo tableProp = typeof(MyDbContext).GetProperty(tableName);
Type tableType = tableProp.PropertyType;
Type pocoType = tableType.GetGenericArguments()[0];
int id = (int)type.GetProperty("ID").GetValue(domainObject);
using (var context = new MyDbContext())
{
object table = tableProp.GetValue(context);
MethodInfo singleMethod = tableType.GetMethod("Single");
}
}
Run Code Online (Sandbox Code Playgroud)
通常,知道实际的表而不仅仅是它的类型,我现在会通过
var poco = context.TableName.Single(item => item.ID == id);
Run Code Online (Sandbox Code Playgroud)
这里有2个问题:
(1)Single是一种扩展方法。
(2) 我不知道如何以 an …
我们正在使用这个组件www.codeeffects.com,它允许我们根据对象属性创建业务规则。
视图的html是这样的:
@{
ViewBag.Title = "Post Example";
Html.CodeEffects().Styles()
.SetTheme(ThemeType.Gray)
.Render();
}
@using (Html.BeginForm("Evaluate", "Post", FormMethod.Post))
{
<div class="area">
<h1 class="title">Post Example</h1>
<div style="margin-top:10px;">
<span>Info:</span>
<span style="color:Red;">@ViewBag.Message</span>
</div>
<div style="margin-top:10px;">
@{
Html.CodeEffects().RuleEditor()
.Id("ruleEditor")
.SaveAction("Save", "Post")
.DeleteAction("Delete", "Post")
.LoadAction("Load", "Post")
.Mode(RuleType.Execution)
.ContextMenuRules(ViewBag.ContextMenuRules)
.ToolBarRules(ViewBag.ToolBarRules)
.Rule(ViewBag.Rule)
.Render();
}
</div>
</div>
<div class="area">
<h1 class="title" style="margin-top:20px;">Rule Test Form</h1>
@{
Html.RenderPartial("_PatientForm");
}
</div>
}
@{
Html.CodeEffects().Scripts().Render();
}
Run Code Online (Sandbox Code Playgroud)
控制器中的索引操作如下:
[HttpGet]
public ActionResult Index()
{
ViewBag.Rule = RuleModel.Create(typeof(Patient));
return View();
}
Run Code Online (Sandbox Code Playgroud)
Patient 类是这样的:
// External methods …Run Code Online (Sandbox Code Playgroud) 在我的一个库中,我有从表达式返回MethodInfo的代码:
public MethodInfo GetMethod(Expression expression)
{
var lambdaExpression = (LambdaExpression)expression;
var unaryExpression = (UnaryExpression)lambdaExpression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
var methodInfoExpression = (ConstantExpression)methodCallExpression.Arguments.Last();
return (MethodInfo)methodInfoExpression.Value;
}
Run Code Online (Sandbox Code Playgroud)
我有一系列辅助函数来启用如下调用:
public MethodInfo Func<T, R, A1>(Expression<Func<T, Func<A1, R>>> expression)
{
return GetMethod(expression);
}
Run Code Online (Sandbox Code Playgroud)
这将启用以下语法:
var methodInfo = Func<TestClass, bool, string>(x => x.AnInstanceMethodThatTakesAStringAndReturnsABool);
Run Code Online (Sandbox Code Playgroud)
这很好用,直到我最近将库升级到.Net 4.6.1和最新的c#编译器.
在.net的早期版本中,表达式将采用以下形式:
{x => Convert(CreateDelegate(System.Func`2[System.String, System.Boolean], x, Boolean AnInstanceMethodThatTakesAStringAndReturnsABool(System.String)))}
Run Code Online (Sandbox Code Playgroud)
因此,我的代码会将methodInfoExpression作为methodCallExpression的最后一个参数.
现在,在.Net 4.6.1(最新的c#编译器)中,编译器似乎正在生成一个不同形式的表达式:
{x => Convert(Boolean AnInstanceMethodThatTakesAStringAndReturnsABool(System.String).CreateDelegate(System.Func`2[System.String, System.Boolean], x))}
Run Code Online (Sandbox Code Playgroud)
我当前的代码中断,因为最后一个参数不是ConstantExpression.看着它 - 轻松修复,只需改为
var methodInfoExpression = (ConstantExpression)methodCallExpression.Object;
Run Code Online (Sandbox Code Playgroud)
显然,GetMethod函数非常脆弱,并且可能会改变编译器生成表达式的方式.我很好奇这个更改的原因以及我如何重构GetMethod,以便它对编译器生成的表达式树更具弹性.
我的目标是显示有关上传的 dll 中某些类的方法的信息。加载程序集、找到所需的类及其方法已经成功完成。现在我试图显示一个方法是否被声明为“异步”。
我发现一个线程告诉我如何做到这一点:How can I Tell if a C# method is async/await via Reflection?
不管怎样,在测试时,当我打电话时
(AsyncStateMachineAttribute)methodInfo.GetCustomAttribute(typeof(AsyncStateMachineAttribute))
我收到 System.IO.FileNotFoundException -“无法加载文件或程序集“{程序集标识符}”或其依赖项之一。系统找不到指定的文件。”。
我在一个未答复的线程中发现了此异常,但它对我没有帮助:How to Prevent MemberInfo.IsDefined from throwing FileNotFoundException on irrelevant attribute?
我知道我正在查看的方法有一个我的代码不知道的属性。我不想加载该引用,因为它只是一个测试用例,在相同的情况下可以找到许多其他不同的属性。
因此,我需要回答以下两个问题之一:
有没有办法获取属性“AsyncStateMachineAttribute”(如果存在),并忽略其他属性上的错误?
是否有另一种方法来检查方法(来自 MethodInfo)是否是异步的?
提前致谢!:)
假设我有一个被声明为给定基类的实例变量。我想找到该对象实际上是什么原始的、最上面的类型,而不是基类。我该怎么做呢?
我有一个类似于 PostSharp 的验证属性,因此反射命中是在编译时发生的,因此由于该CompileTimeValidation方法而没有实际意义。我只是不知道该怎么做。进行IsSubclassOf扫描没有帮助,因为我会得到多个误报。
为了提供上下文,我有一个基本Entity类型。我从这个类型派生出所有类型的定义Entity。我Entity使用策略属性来装饰这些类型,包括基本类型。PostSharp 方面在编译时验证某些策略约束。我希望能够仅使用Entity方面验证来装饰基类型,以便Entity验证其所有派生类型。我可以看到验证已经发生。但是,它被作为 anEntity和 not处理DerivedEntity。为了评估 的策略DerviedEntity,我需要专门装饰该类。如果可能的话我想不这样做,而只是装饰Entity。
本质上,我想将验证集中在基类上,因为所有派生类的验证架构都是相同的。但是,派生类中的值可能会更改,我需要进行一些边界检查。
编辑:让我们添加一些代码。
[EnforceMaxLifetimePolicy]
[LifetimePolicy]
public class Entity<T>
{
public string Key { get; set; }
public T Object { get; set; }
public TimeSpan EntityLifetime
{
get
{
var lifetimePolicy =
Attribute.GetCustomAttribute(GetType(), typeof(LifetimePolicyAttribute)) as LifetimePolicyAttribute;
return new TimeSpan(lifetimePolicy.Hours, lifetimePolicy.Minutes, 0);
}
}
}
[Serializable]
[AttributeUsage(AttributeTargets.Class)]
internal class LifetimePolicyAttribute : …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写接收参数列表并获取匹配 Ctor 的 ConstructorInfo 的代码。
方法签名是ConstructorInfo GetConstructorInfo(Type type, object[] args).
我创建了一个类来使用:
public class ClassWithParamsInCtor
{
public ClassWithParamsInCtor(params int[] parameters)
{
}
}
Run Code Online (Sandbox Code Playgroud)
使用该类Activator我可以创建该对象的实例:
ClassWithParamsInCtor myclass = Activator.CreateInstance(typeof(ClassWithParamsInCtor), new object[] { 1,2 }) as ClassWithParamsInCtor; \\returns a valid instance of the class;
Run Code Online (Sandbox Code Playgroud)
但是当我尝试获取 ConstructorInfo 时出现问题,以下返回 null:
ConstructorInfo ctorInfo = typeof(ClassWithParamsInCtor).GetConstructor(new Type[] { typeof(int), typeof(int) }); \\returns null
Run Code Online (Sandbox Code Playgroud)
在这种情况下如何获取ConstructorInfo?
我正在尝试使用它的名称动态System.Reflections获取DbSet<T>。
我现在有的是:
DbSet名DbSet的Type存储在可变在尝试使用该dbcontext.Set<T>()方法时,我面临的问题出现了,因为(这些是我迄今为止的尝试):
<T>my 时DbSet Type,它会引发以下编译错误:
“XXX 是一个变量,但像类型一样使用”
Extension方法,您将在我的代码下面找到(我为了设法弄一本制作IQueryable<T>),它返回一个IQueryable<object>,不幸的是不是我期待的,因为当然,当我尝试用进一步的反射操作它,它缺少原始类具有的所有属性......我究竟做错了什么?我怎样才能得到一个DbSet<T>?
我的代码如下,当然,如果您需要更多信息、说明或代码片段,请告诉我。
我的控制器的方法:
public bool MyMethod (string t, int id, string jsonupdate)
{
string _tableName = t;
Type _type = TypeFinder.FindType(_tableName); //returns the correct type
//FIRST TRY
//throws error: "_type is a variable but is used like a type"
var tableSet = _context.Set<_type>();
//SECOND …Run Code Online (Sandbox Code Playgroud) 当尝试从派生属性获取属性访问器或使用 CanRead / CanWrite 时,出于某种原因,不考虑基本自动属性。
CanRead并CanWrite仅基于派生类型返回值,GetMethod以及SetMethod没有包含来自基类型的方法。
但是,当从基类型编写代码访问器时,可以使用(这样我们可以仅使用派生类型中定义的 setter 读取覆盖的自动属性)。
这是作为单元测试编写的重现它的代码:
using System.Reflection;
using NUnit.Framework;
[TestFixture]
public class PropertiesReflectionTests
{
public class WithAutoProperty
{
public virtual object Property { get; set; }
}
public class OverridesOnlySetter : WithAutoProperty
{
public override object Property
{
set => base.Property = value;
}
}
private static readonly PropertyInfo Property = typeof(OverridesOnlySetter).GetProperty(nameof(OverridesOnlySetter.Property));
// This one is passing
[Test]
public void Property_ShouldBeReadable()
{
var overridesOnlySetter = new OverridesOnlySetter {Property …Run Code Online (Sandbox Code Playgroud) c# ×10
reflection ×4
.net ×3
asp.net ×1
asp.net-core ×1
asp.net-mvc ×1
asynchronous ×1
constructor ×1
gac ×1
postsharp ×1
system.type ×1
validation ×1