Доступ к свойству объекта DisplayClass во время выполнения - PullRequest
0 голосов
/ 13 марта 2019

Среда: VS2017, C # 7.0 для .NET Core 2.1.

Я пытаюсь написать фиктивный / фиктивный класс для использования в модульном тестировании, и у меня возникают трудности с доступом к свойству объекта DisplayClass, который, как я понимаю, является классом закрытия из анонимной функции .

Мой код выглядит так:

namespace MyCompany.Application.Web.Test.Fakes
{
    public class FakeElasticClient : IElasticClient
    {
        public FakeElasticClient() { }

        public Task<ISearchResponse<T>> SearchAsync<T>(Func<SearchDescriptor<T>, ISearchRequest> selector = null, CancellationToken cancellationToken = default(CancellationToken)) where T : class
        {
            var methodName = selector.Method.Name;
            dynamic tgt = selector.Target;
            object id = tgt?.GetType().GetProperty("id")?.GetValue(tgt, null);
            int? total;
            if (methodName.Contains("Quux"))
            {
                total = CountSomething((Guid)id);
            }
            else
            {
                total = CountSomethingElse((Guid)id);
            }

            return Task.Run(() => new FakeSearchResponse<T>(total ?? 0) as ISearchResponse<T>);
        }

        // … below here follows a couple thousand other methods

При преобразовании id к Guid выдается NullReferenceException, хотя отладчик Visual Studio показывает, что объект tgt имеет свойство id:

Visual Studio debugger

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

  • Я украл object id = … строку из этого ответа .
  • tgt.GetType() возврат MyCompany.Application.Domain.Repository.Implementations.BusinessEntityRepository.<>c__DisplayClass8_0
  • tgt.GetType().GetProperties() возвращает пустой массив PropertyInfo.
  • Вдохновленный этим сообщением в блоге Я добавил атрибут [assembly: InternalsVisibleTo("MyCompany.Application.Web.Test")] к классам MyCompany.Application.Domain.Repository.Implementations.BusinessEntityRepository и MyCompany.Application.Web.Controllers, которые, насколько я могу судить, являются единственными двумя классами, вовлеченными в вызов цепь. Не имеет никакого значения.
  • Я пытался суетиться с IgnoresAccessChecksTo , как описано здесь , но не смог ничего скомпилировать.

Как мне получить значение для id?

1 Ответ

1 голос
/ 13 марта 2019

Компилятор генерирует типы замыканий с полями, а не со свойствами, поэтому id является полем.Вместо этого используйте tgt.GetType().GetFields().

...