使用反射加载程序集 - 'object' 不包含 'Description' 的定义?
Loading assembly with reflection - 'object' does not contain a definition for 'Description'?
我们需要在运行时加载 mongodb c# 程序集。
( 原因:通过 nuget 附加到应用程序的健康检查服务,需要检查应用程序的 mongo 连接,但它应该使用现有的 (!) mongo dll 在 BIN 中。没有自带一个,因此通过反射加载 mongo)
我只需要检查这段代码:
MongoClient client = new MongoClient(mongoConnection);
var res = client.Cluster.Description.State == ClusterState.Connected;
我已经完成了第一部分:
Assembly dll = Assembly.LoadFile(@"C:\Users\RoyiNamir\....\MongoDB.Driver.dll");
Type type = dll.GetType("MongoDB.Driver.MongoClient");
Console.WriteLine(type); //MongoDB.Driver.MongoClient
dynamic client = Activator.CreateInstance(type, mongoConnection);
Console.WriteLine(client.Cluster.Description );
我在最后一行遇到异常,我尝试打印 client.Cluster.Description
:
Message
'object' does not contain a definition for 'Description'
Source
Anonymously Hosted DynamicMethods Assembly
StackTrace
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at UserQuery.Main()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
但是 - 如果我改为执行 Console.WriteLine(client.Cluster);
,那么我会得到结果:
使用反射器,我看到 Description 是:
ClusterDescription Description { get; }
其中 ClusterDescription 是:
public sealed class ClusterDescription : IEquatable<ClusterDescription> {}
问题:
为什么抛出异常?
使用 dynamic/reflection,如何访问 Description
属性?
这是因为 class 显式实现了 Description
属性。因此,您的代码应该看起来像这样才能修复它。也就是说,您需要显式转换为正确的接口。
dynamic c =Activator.CreateInstance(type);
Console.WriteLine(((ICluster)c.Cluster).Description);
或者您可以像下面这样使用所有动态:
dynamic c =Activator.CreateInstance(type);
var targetType = type.GetProperties().Where(x => x.Name == "Cluster").Single().PropertyType;
Console.WriteLine(targetType.GetProperty("Description").GetValue(c.Cluster));
我们需要在运行时加载 mongodb c# 程序集。
( 原因:通过 nuget 附加到应用程序的健康检查服务,需要检查应用程序的 mongo 连接,但它应该使用现有的 (!) mongo dll 在 BIN 中。没有自带一个,因此通过反射加载 mongo)
我只需要检查这段代码:
MongoClient client = new MongoClient(mongoConnection);
var res = client.Cluster.Description.State == ClusterState.Connected;
我已经完成了第一部分:
Assembly dll = Assembly.LoadFile(@"C:\Users\RoyiNamir\....\MongoDB.Driver.dll");
Type type = dll.GetType("MongoDB.Driver.MongoClient");
Console.WriteLine(type); //MongoDB.Driver.MongoClient
dynamic client = Activator.CreateInstance(type, mongoConnection);
Console.WriteLine(client.Cluster.Description );
我在最后一行遇到异常,我尝试打印 client.Cluster.Description
:
Message
'object' does not contain a definition for 'Description'
Source
Anonymously Hosted DynamicMethods Assembly
StackTrace
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at UserQuery.Main()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
但是 - 如果我改为执行 Console.WriteLine(client.Cluster);
,那么我会得到结果:
使用反射器,我看到 Description 是:
ClusterDescription Description { get; }
其中 ClusterDescription 是:
public sealed class ClusterDescription : IEquatable<ClusterDescription> {}
问题:
为什么抛出异常?
使用 dynamic/reflection,如何访问 Description
属性?
这是因为 class 显式实现了 Description
属性。因此,您的代码应该看起来像这样才能修复它。也就是说,您需要显式转换为正确的接口。
dynamic c =Activator.CreateInstance(type);
Console.WriteLine(((ICluster)c.Cluster).Description);
或者您可以像下面这样使用所有动态:
dynamic c =Activator.CreateInstance(type);
var targetType = type.GetProperties().Where(x => x.Name == "Cluster").Single().PropertyType;
Console.WriteLine(targetType.GetProperty("Description").GetValue(c.Cluster));