В наших тестах компонентов возникла действительно непостоянная проблема, которую можно найти чуть ниже:
- 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 ---