Исключение ReflectionTypeLoadException при использовании с Asp.Net Core в памяти TestServer - PullRequest
0 голосов
/ 07 июня 2019

В наших тестах компонентов возникла действительно непостоянная проблема, которую можно найти чуть ниже:

  • System.Reflection.ReflectionTypeLoadException: невозможно загрузить один или несколько запрошенных типов.

Это исчерпывающий пример того, что происходит, что было просто отключено разработчиками автомобилей: https://github.com/AutoMapper/AutoMapper/issues/2973

Я не совсем уверен, что является причиной этого, но мы только что внесли большие изменения в базы данных в памяти, так как люди утверждают, что это маршрут, поэтому я не удивлюсь, если это проблема. Если у вас есть какой-либо опыт с этим или вы можете обнаружить что-то не так с фрагментами ниже, это было бы здорово, так как я потерял на этом.

Ниже приведена трассировка стека, описывающая возникшую ошибку.

Создайте какое-то промежуточное программное обеспечение для исключения, чтобы выявить проблему (код можно увидеть ниже), поскольку это происходит только на стороне тестового сервера, и при изучении этого все, кто сталкивался с этой проблемой, использовали БД в памяти.

НАСТРОЙКА ИСПЫТАНИЙ

   public class PermissiveTestServerFactory : WebApplicationFactory<Startup>
   {
       protected override void ConfigureWebHost(IWebHostBuilder builder)
       {
           builder.UseContentRoot(".");
           base.ConfigureWebHost(builder);
       }

       protected override IWebHostBuilder CreateWebHostBuilder()
       {
           var serviceProjectPath = Path.Combine(GetSolutionFolder(), "src", "Zupa.Products.ProductsService");

           return WebHost.CreateDefaultBuilder()
               .UseConfiguration(new ConfigurationBuilder()
               .SetBasePath(serviceProjectPath)
               .AddJsonFile("appsettings.json", optional: false)
               .Build())
               .Configure(builder => builder.UseMiddleware<LoaderExceptionHandler>())
               .UseEnvironment(EnvironmentName.Development)
               .UseStartup<Startup>()
               .ConfigureTestServices(services =>
               {
                   services.AddAuthentication(options =>
                   {
                       options.DefaultAuthenticateScheme = "Permissive Scheme";
                       options.DefaultChallengeScheme = "Permissive Scheme";
                   }).AddTestAuthentication(o => { });

                   services.AddScoped<DbContextOptions<TradingDbContext>>(provider =>
                   {
                       var builder = new DbContextOptionsBuilder<TradingDbContext>(
                               new DbContextOptions<TradingDbContext>(
                                   new Dictionary<Type, IDbContextOptionsExtension>()));

                       builder.UseApplicationServiceProvider(provider);

                       builder.UseSqlServer(TestConstants.SQLConnectionString);

                       return builder.Options;
                   });

                   services.AddTestCosmosClient<ProductEntity>();
                   services.AddTestCosmosClient<ProductCategoryEntity>();
                   services.AddTestCosmosClient<InternalPriceListEntity>();
                   services.AddTestCosmosClient<PurchasePricesEntity>(config =>
                   {
                       config.IdPropertyName = nameof(PurchasePricesEntity.PurchaserId);
                   });

                   services.AddSingleton<ICosmosClient<BrandEntity>>(_ =>
                       new TestCosmosClient<BrandEntity>(config =>
                       {
                           config.IdPropertyName = nameof(BrandEntity.Name);
                       }));

                   services.AddTransient<IProductsRepository>(provider =>
                       new ProductsRepository(
                           provider.GetRequiredService<ICosmosClient<ProductEntity>>(),
                           provider.GetRequiredService<IMapper>()));

                   services.AddTransient<IProductCategoriesRepository>(provider =>
                       new ProductCategoriesRepository(
                           provider.GetRequiredService<ICosmosClient<ProductCategoryEntity>>(),
                           provider.GetRequiredService<IMapper>(),
                           provider.GetRequiredService<IProductsRepository>()));

                   services.AddTransient<IBrandsRepository>(provider =>
                      new BrandsRepository(
                          provider.GetRequiredService<ICosmosClient<BrandEntity>>(),
                          provider.GetRequiredService<IMapper>(),
                          provider.GetRequiredService<ITelemetryTracker>()));

                   services.AddTransient<ITradingUnitOfWork>(provider =>
                   {
                       var tradingDbContext = provider.GetRequiredService<ITradingDbContextFactory>();
                       var mapper = provider.GetRequiredService<IMapper>();
                       var priceListReadRepository = provider.GetRequiredService<IPriceListReadRepository>();
                       var dbExceptionInterpreter = provider.GetRequiredService<IDbExceptionInterpreter>();

                       return
                           new TradingUnitOfWorkSchemaGenerator(
                               new TradingUnitOfWork(
                                   tradingDbContext,
                                   mapper,
                                   priceListReadRepository,
                                   dbExceptionInterpreter
                               ),
                               tradingDbContext
                           );
                   });

                   services.Configure<DefaultDataSettings>(config =>
                   {
                       config.ProductCategories = DefaultData.ProductCategories;
                       config.BrandNames = DefaultData.BrandNames;
                   });

                   services.Configure<TableStorageSettings>(config =>
                   {
                       config.ConnectionString = TestConstants.TableStorageConnectionString;
                       config.TableName = TestConstants.TableStorageTableName;
                   });
               });
       }

       private static string GetSolutionFolder()
       {
           var folder = new DirectoryInfo(PlatformServices.Default.Application.ApplicationBasePath);

           while (folder != null && !folder.GetFiles("*.sln").Any())
               folder = folder.Parent;

           if (folder == null)
               throw new FileNotFoundException("Cannot find solution folder for the current project");

           return folder.FullName;
       }
   }

LoaderExceptionHandler

public class LoaderExceptionHandler
    {
        private readonly RequestDelegate _delegate;
        private readonly ILogger _logger;

        public LoaderExceptionHandler(RequestDelegate requestDelegate, ILogger<LoaderExceptionHandler> logger)
        {
            _delegate = requestDelegate;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _delegate(context);
            }
            catch (ReflectionTypeLoadException e)
            {
                foreach (Exception ex in e.LoaderExceptions)
                {
                    _logger.LogCritical(ex.Message + Environment.NewLine + ex.StackTrace);
                }
            }
        }
    }
System.Reflection.ReflectionTypeLoadException : Unable to load one or more of the requested types.
[11:12:03][Step 1/1] Could not load type 'Castle.Proxies.IOrganisationsServiceProxyProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
[11:12:03][Step 1/1] Could not load type 'Castle.Proxies.Invocations.IOrganisationsServiceProxy_GetOrganisationChildrenAsync' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
[11:12:03][Step 1/1] Stack Trace:
[11:12:03][Step 1/1]    at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
[11:12:03][Step 1/1]    at System.Reflection.RuntimeAssembly.get_DefinedTypes()
[11:12:03][Step 1/1]    at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.ToArray()
[11:12:03][Step 1/1]    at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
[11:12:03][Step 1/1]    at AutoMapper.ServiceCollectionExtensions.AddAutoMapperClasses(IServiceCollection services, Action`2 configAction, IEnumerable`1 assembliesToScan) in C:\projects\automapper-extensions-microsoft-dependencyinjectio\src\AutoMapper.Extensions.Microsoft.DependencyInjection\ServiceCollectionExtensions.cs:line 72
[11:12:03][Step 1/1]    at Zupa.Products.ProductsService.Startup.ConfigureServices(IServiceCollection services) in C:\BuildAgent_v10\work\89160412962c53ca\src\Zupa.Products.ProductsService\Startup.cs:line 138
[11:12:03][Step 1/1] --- End of stack trace from previous location where exception was thrown ---
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize()
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.TestHost.TestServer..ctor(IWebHostBuilder builder, IFeatureCollection featureCollection)
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateServer(IWebHostBuilder builder)
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
[11:12:03][Step 1/1]    at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
[11:12:03][Step 1/1]    at Zupa.Products.ProductsService.ComponentTests.PriceListV2Tests.EditPriceList_OrganisationIdEmpty_ReturnsBadRequest() in C:\BuildAgent_v10\work\89160412962c53ca\test\Zupa.Products.ProductsService.ComponentTests\PriceListV2Tests.cs:line 481
[11:12:03][Step 1/1] --- End of stack trace from previous location where exception was thrown ---
...