【发布时间】:2021-08-01 04:54:56
【问题描述】:
在我的用例中,我需要根据上下文映射属性。
请记住,我通过调用 ProjectTo 函数将 Automapper 与实体框架一起使用。所以遗憾的是,自定义值解析器是没有选择的。
简单示例:
public class Comment
{
public int Id { get;set; }
public int UserId { get;set; }
...
}
public class Source
{
public int Id { get; set; }
public IEnumerable<Comment> Comments { get; set; }
}
public class Destination
{
public int Id { get; set; }
public int NumOwnComments { get; set; }
}
基本上,Destination 应该包含自己的 cmets 的数量。
当前用户是使用带有属性UserId 的ICurrentUserService 动态解析的。
我已经通过以下方式解决了这个问题:
在Startup.cs 中我添加了Transient 映射器/配置。
services.AddTransient(provider => new MapperConfiguration(cfg => { cfg.AddProfile(new MappingProfile(provider.GetService<ICurrentUserService>())); })
.CreateMapper());
然后我在 MappingProfile 中按以下方式创建了映射:
public class MappingProfile : Profile {
public MappingProfile(ICurrentUserService currentUserService) {
CreateMap<Source, Destination>()
.ForMember(vm => vm.NumOwnComments, opts => opts.MapFrom(s => s.Comments.Count(c => c.UserId == currentUserService.UserId))
;
}
}
虽然这可行,但将映射器配置作为瞬态/作用域依赖项并不是很好。每个请求都会创建这个映射器,这会消耗大量内存和 CPU 周期。
有没有更优雅的方法,比如将映射配置文件创建为单例,然后在作用域/瞬态映射器中执行它?
【问题讨论】:
-
哇,我怎么会错过……谢谢,我会试试的。您对如何在整个项目中管理参数有什么建议吗?自定义 ProjectTo 扩展方法,例如
ProjectToDestinationDto(currentUser)? -
应该可以。试一试:)
-
非常感谢它运行良好并解决了我的性能问题!
标签: c# asp.net-core dependency-injection entity-framework-core automapper