ASP.NET Core 2.0:AutoMapper IValueResolver 依赖注入

8
我已经尝试了Google结果、Stackoverflow和AutoMapper中的大多数示例,但无法使IValueResolver依赖注入起作用。
我有以下服务。
public class StorageService : IStorageService
{
    private readonly BlobServiceSettings _blobServiceSettings;

    public StorageService(IOptions<BlobServiceSettings> blobServiceSettings)
    {
        _blobServiceSettings = blobServiceSettings.Value;
    }

    // some methods I need
}

这是我的个人资料。
public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<Building, BuildingEnvelope>(MemberList.None)
        .ForMember(dest => dest.ImageUrl, opt => opt.ResolveUsing<BuildingImageUrlResolver>());
    }
}

这是我的 IValueResolver。
public class BuildingImageUrlResolver : IValueResolver<Building,         BuildingEnvelope, string>
{
    private readonly IStorageService _storageService;
    public BuildingImageUrlResolver(IStorageService storageService)
    {
        _storageService = storageService;
    }

    public string Resolve(Building entity, BuildingEnvelope envelope, string member, ResolutionContext context)
    {               
        return _storageService.MyMethod(entity.ImageFileName);
    }
}

我在内部异常中收到以下错误:
“此对象没有定义无参数构造函数。”
不确定我做错了什么。
提前致谢。 Neo

错误是否标识了哪个类?无论如何,我怀疑你需要 public StorageService() 或者 public BuildingImageUrlResolver() - F Rowe
https://github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection - Lucian Bargaoanu
一旦我在构造函数中使用DI,就会出现这个错误。 - NeroIsNoHero
1个回答

4
卢西安的建议是正确的 - AutoMapper.Extensions.Microsoft.DependencyInjection 包是最好的选择。即使您不想使用它,您也需要做类似的事情。
我曾经遇到过同样的问题,通过使用这些扩展,您只需要修改注册 AutoMapper 的入口点及其配置即可。
这些扩展所做的 (源码) 是:
  1. 使用提供的配置初始化 Automapper。
  2. 它会扫描所有你可能用依赖注入实现的类,并将它们注册为瞬态,查找以下实现:

    • IValueResolver
    • IMemberValueResolver
    • ITypeConverter
    • IMappingAction

    要扫描的程序集实际上取决于您在调用时提供的参数。

  3. 如果其中任何一个可以被实例化,那么它们将被注册为瞬态实现。
  4. 就像这样,AutoMapper 将请求服务提供程序的这些实例,服务提供程序将解析它们,并为此解析任何待定的依赖项。
请注意,这实际上非常简单 - 最困难的部分是扫描正确的程序集并注册正确的类。您也可以手动完成,但是这些扩展已经为您处理了。
请注意,即使反射已经得到了很大改进,这个过程相对较慢,因此不要过度滥用它(例如在测试中)。
最后,如果所有这些都不适用于您,请记住您需要设置 AutoMapper 使用依赖注入解析器:
automapperConfiguration.ConstructServicesUsing(serviceProvider.GetService);

抱歉回复晚了,我在度假,现在回来了。我之前尝试使用AutoMapper.Extensions.Microsoft.DependencyInjection,但是出现了相同的问题,我想可能与项目有关。IStorageService也像下面这样具有依赖项注入 public StorageService(IOptions<BlobServiceSettings> blobServiceSettings) { _blobServiceSettings = blobServiceSettings.Value; }不确定是否是个问题,可以尝试删除它并进行测试,但是由于服务广泛用于整个项目,我将无法永久删除它。谢谢 - NeroIsNoHero
我尝试移除IStorageService中的DI,但仍然出现错误。显然是与解析器DI有关,还有更多的想法吗? - NeroIsNoHero
@NeroIsNoHero 你尝试传递参数给扩展方法,以便它可以扫描正确的程序集吗? - Alpha
你好Alpha,感谢您的回复,是的,我在startup.cs中进行了这个操作 [code]services.AddAutoMapper(typeof(IStorageService));[/code]如果我在“StorageService”的构造函数中设置断点,它会被触发并解决其依赖项(从应用程序设置中获取URL)。错误映射类型。映射类型: Building -> BuildingEnvelope Building -> BuildingEnvelope类型映射配置: Building -> BuildingEnvelope Building -> BuildingEnvelope属性: ImageUrl有什么想法吗?我已经苦恼了几个月了,能够解决问题就太好了。谢谢 - NeroIsNoHero
一旦我从构造函数中删除 DI,就没有错误了。 - NeroIsNoHero
基于这个错误,看起来解析器正在被调用(耶!),只是内部失败了。我建议你进行调试并验证为什么会崩溃--这是更简单的方法,因为Automapper不会详细告诉您异常是什么,只会告诉您映射失败了。(简单的方法:在整个Resolve方法上使用try/catch,并在catch中设置断点。) - Alpha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接