• 【aspnetcore】在asp.net core中配置使用AutoMapper


    网上使用AutoMapper的文章很多,就不多说了。这里主要记录一下怎么在项目中配置和使用。

    首先是从NuGet获取AutoMapper。

    在Startup.cs文件中注册AutoMapper服务

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAutoMapper();
    }

    一般把AutoMapper的映射关系单独写在一个Profile文件,比如个人习惯在Service层添加一个ServiceProfile.cs文件(这是因为所有的实体和Dto都是在Service层定义的),可能的样子如下:

    public class ServiceProfiles : Profile
    {
        public ServiceProfiles()
        {
            CreateMap<WxAccount, WxAccountSessionDto>();
            CreateMap<WxNews, WxNewsListDto>();
            CreateMap<WxMessage, WxMessageListDto>()
                .ForMember(w => w.MatchType, opts =>
                {
                    opts.ResolveUsing<WxMessageListDtoResolver>();
                });
        }
    }

    这个文件也没什么好说的,必须继承自AutoMapper.Profile,在构造函数中创建映射关系,具体使用可看看其他大神的文章,这里就不班门弄斧了。

    接下来就是最后一步,在项目中使用定义的ServiceProfile,AutoMapper提供了一个Initialize方法,具体用法如下:

    Mapper.Initialize(cfg =>
    {
        cfg.AddProfile<ServiceProfiles>();
    });

    这里要注意这句代码的位置,要写在Startup.cs的构造函数内

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    
        LoggerRepository = LogManager.CreateRepository("NETCoreRepository");
        XmlConfigurator.Configure(LoggerRepository, new FileInfo(Environment.CurrentDirectory + "\Config\log4net.config"));
    
        Mapper.Initialize(cfg =>
        {
            cfg.AddProfile<ServiceProfiles>();
        });
        Mapper.AssertConfigurationIsValid();
    }

    之前就是因为把初始化代码写在ConfigureServices方法内导致配置项不起作用,特此标记。

    上面的理解有误,请参考下面的说明:

    一般来讲,在ConfigureServices中注册AutoMapper服务只要如下代码即可:

    services.AddAutoMapper();

    AutoMapper会从程序集中搜索Profile的子类,然后把这些子类加入到配置中。如果Profile文件是在当前程序中定义,那没有问题,但如果是写在外部类库内,则是搜索不到的,所以类似我的做法,把Profile定义在类库内,需要手动把配置文件加入到AutoMapper的配置中,如下:

    services.AddAutoMapper(cfg =>
    {
        cfg.AddProfile(typeof(ServiceProfiles));
    });

    但是,如果仅仅这样,如同我上面的ServiceProfile是不能正确运行的,因为我定义了一个 WxMessageListDtoResolver 这样一个 IValueResolver 接口的实现,说到这里大家应该猜到,AutoMapper没法自动调用这个实现,需要我们添加注入,所以还要加入这样一句

    services.AddSingleton<WxMessageListDtoResolver>();

    这样程序就可以正常使用了。

    但是,想象一下,如果我们的类库中如果定义了很多IValueResolver,是不是每个都要注册一次呢,想想都是噩梦,所以,这里还有一个办法,就是使用Mapper的Initialize方法,提前把Profile传递进去,再调用AddAutoMapper时,会自动将所有的Profile内用到的几个接口如IValueResolver,IMemberValueResolver的实现注入到程序,这样就可以了。所以,我之前的理解是错误的,并不需要把Initialize写到Startup的构造函数内,只要在AddAutoMapper之前就可以了。

    所以,建议的写法,在ConfigureServices方法内:

     Mapper.Initialize(cfg =>
    {
        cfg.AddProfile<ServiceProfiles>();
    });
    
    services.AddAutoMapper();

    结束,谢谢~

  • 相关阅读:
    [CF1355] Codeforces Round #643 (Div. 2)
    [ABC189] AtCoder Beginner Contest 189
    P3702 [SDOI2017]序列计数 (三模数NTT)
    P3321 [SDOI2015]序列统计 (NTT快速幂)
    洛谷P4157 [SCOI2006]整数划分
    洛谷P2553 [AHOI2001]多项式乘法
    洛谷P1919 (模板)A*B Problem升级版(FFT快速傅里叶)
    MySQL学习总结-详细版(包括下载安装)
    查看oracle数据库中表是否被锁
    SQL优化(面试题)
  • 原文地址:https://www.cnblogs.com/diwu0510/p/9754263.html
Copyright © 2020-2023  润新知