我有一个带有自定义映射器集的项目,该映射器在模型和视图模型之间进行映射。每个映射器都可以访问IServiceProvider
以便为其内部对象获取相应的映射器。像这样:
public class OuterMapper : MapperBase<OuterModel, OuterViewModel>
{
public OuterMapper(IServiceProvider serviceProvider, IMyDbContext dbContext)
: base(serviceProvider, dbContext)
{}
public override async Task<OuterModel> ToModel(OuterViewModel viewModel, OuterModel existingModel)
{
var model = existingModel
?? (await base.DbContext.OuterModels.SingleAsync(x => x.Id == viewModel.Id))
?? new OuterModel();
model.SimpleProperty = viewModel.SimpleProperty;
model.InnerComplexObject = await base.ToInnerModel(viewModel.InnerComplexObject, model.InnerComplexObject);
return model;
}
public override async Task<OuterViewModel> ToViewModel(OuterModel model, OuterViewModel existingViewModel)
{
var viewModel = existingViewModel ?? new OuterViewModel();
viewModel.SimpleProperty = model.SimpleProperty;
viewModel.InnerComplexObject = await base.ToInnerViewModel(model.InnerComplexObject, viewModel.InnerComplexObject);
return viewModel;
}
}
public abstract class MapperBase<TModel, TViewModel> : IMapper<TModel, TViewModel>
{
private IServiceProvider ServiceProvider { get; set; }
protected IMyDbContext DbContext { get; private set; }
public MapperBase(IServiceProvider serviceProvider, IMyDbContext dbContext)
{
ServiceProvider = serviceProvider;
DbContext = dbContext;
}
protected async Task ToInnerModel<TInnerModel, TInnerViewModel>(TInnerViewModel viewModel, TInnerModel model)
{
var innerMapper = ServiceProvider.GetService<IMapper<TInnerModel, TInnerViewModel>>();
return await innerMapper.ToModel(viewModel, model);
}
protected async Task ToInnerViewModel<TInnerModel, TInnerViewModel>(TInnerModel model, TInnerViewModel viewModel)
{
var innerMapper = ServiceProvider.GetService<IMapper<TInnerModel, TInnerViewModel>>();
return await innerMapper.ToViewModel(model, viewModel);
}
}
最近,我们已经开始将代码重构,以从同步操作转变为异步操作(如示例映射程序中已经看到的那样)。但是,这导致了不可预测的附带问题。当映射具有很多嵌套对象的非常复杂的对象时,有时会在下面的代码行中出现静默崩溃:
var innerMapper = ServiceProvider.GetService<IMapper<TInnerModel, TInnerViewModel>>();
基本上,该应用程序似乎已冻结,无法响应新请求。似乎某个地方有一个尚未等待的异步方法,但我们还没有找到任何异步方法。当评估表达式时(在JetBrains Rider中),我收到超时错误消息。我对IServiceProvider
进行了自省,可以看到其中的ResolvedServices
中有一个正确的映射器实例。此外,当我将具有完全相同类型参数的问题行移到项目的另一部分(例如,直接移到控制器中)时,映射器将按预期解决。
可能是什么原因导致此问题? ASP.NET Core中有ServiceProvider
个调用限制吗?
仅需几个细节:我使用的是.NET Core 2.2,它在Windows 10计算机上运行,并使用JetBrains Rider进行开发。
编辑
我使用了JetBrains Rider的“调试外部源”功能,并浏览了一些.NET代码。最后一次致电是在第29-31行打到Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService
,其中this._disposed
被评估为true
。然后,最后一行是ThrowHelper.ThrowObjectDisposedException()
,此后应用程序冻结。为什么要处置提供者?为什么没有捕获异常?