Загрузка сборки с отражением — «объект» не содержит определения для «Описания»?

#c# #mongodb #dynamic #reflection

Вопрос:

Нам нужно загрузить сборку mongodb c# во время выполнения.

( причина: служба проверки работоспособности , подключенная к приложению через nuget, должна проверить приложение на наличие подключения к mongo, но она должна использовать существующую(!) библиотеку DLL mongo в корзине. Не принося с собой ничего своего, следовательно, загружая монго по размышлению)

Все, что мне нужно проверить, это этот код :

   MongoClient client = new MongoClient(mongoConnection);
  var res = client.Cluster.Description.State == ClusterState.Connected;
 

Мне удалось сделать первую часть:

 Assembly dll = Assembly.LoadFile(@"C:UsersRoyiNamir....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); вместо этого , то получу результат :

Одиночный серверный кластер

Используя отражатель, я вижу, что описание :

 ClusterDescription Description { get; }
 

Где описание кластера :

   public sealed class ClusterDescription : IEquatable<ClusterDescription> {}
 

Вопрос:

Почему возникает исключение?
Используя динамику/отражение, как я могу получить доступ к Description свойству?

Ответ №1:

Это происходит потому, что класс 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));
 

Комментарии:

1. я имею в виду вот что : i.imgur.com/HX6wyDu.jpg . У меня нет iCluster, так как все должно быть загружено во время выполнения с помощью отражения.

2. Я обновил код, чтобы удовлетворить ваши требования ко всем динамическим 🙂

3. Работаю, мой друг : i.imgur.com/iOhLimw.jpg

4. Кстати, где вы видели, что класс явно реализует свойство Description.` ?

5. Я знал это по поведению отражения