【发布时间】:2023-03-17 06:34:01
【问题描述】:
我有一个关于 ASP NET Core 中 AutoMapper 依赖注入的问题。我知道在实现自定义IValueResolver 和IMemberValueResolver 时,可以使用 DI 的自动映射器扩展。这仅在 AutoMapper/DI 创建自定义值解析器时才有效。不幸的是,如果我需要手动创建值解析器,这将不起作用。另请注意,当我调用mapper.Map<>() 方法时,我不想传递项目,因为我不希望IMapper 的使用者在运行时知道任何额外的参数
考虑下面的代码:
class Entity1
{
public int MyProperty1 { get; set; }
}
class Dto1
{
public int MyProperty1 { get; set; }
public string CustomProperty { get; set; }
}
在 MyProfile.cs 中
CreateMap<Entity1, Dto1>()
.ForMember(x => x.CustomProperty,
opt => opt.ResolveUsing(new MyCustomPropertyResolver("Important value")));
而 MyCustomPropertyResolver 是这样的:
public class MyCustomPropertyResolver : IValueResolver<Entity1, Dto1, string>
{
string _someValue;
public MyCustomPropertyResolver(string someValue)
{
_someValue = someValue;
}
string Resolve(Entity1 source, Dto1 destination, string destMember, ResolutionContext context)
{
//I need IHttpContextAccessor ..... How can I do that???
}
}
当然,如果我这样做:
CreateMap<Entity1, Dto1>()
.ForMember(x => x.CustomProperty,
opt => opt.ResolveUsing<MyCustomPropertyResolver>()));
我可以使用 DI 并将 IHttpContextAccessor 添加到 MyCustomPropertyResolver 构造函数,但是我将无法将任何额外的参数传递给解析器,这些参数对于解析实际值也很重要。有没有办法做到这一点?我能够实现这一点的唯一方法是在MyProfile 类上添加一个静态属性,并通过服务请求的控制器上的ActionFilter 设置它。虽然这个工作,但我不喜欢这个解决方案,因为它会创建不需要的依赖项。 AutoMapper 上的官方解决方案是这样做的:
// This solution is not good enough for my need
var dto = mapper.Map<Dto1>(entity, opt => { opt.Items["AnyThing"] = Whatever; });
使用上面的代码,我可以将HttpContext 传递给项目字典,但这将使映射器使用者需要传递可能不知道的参数。
我的代码实际上要复杂得多,但它在概念上使用了上面相同的示例。
【问题讨论】:
-
offtop:使用简单的映射器LynxMapper
标签: c# dependency-injection asp.net-core automapper