2

ABP AutoMapper与自定义Mapping - 悟自省

 1 year ago
source link: https://www.cnblogs.com/moonstars/p/16979152.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

ABP AutoMapper与自定义Mapping

在工作中,需要将相似的对象映射到另一个对象,这样我们来看一个最繁琐的映射方式
public class UserAppService : ApplicationService
{
    private readonly IRepository<User> _userRepository;

    public UserAppService(IRepository<User> userRepository)
    {
        _userRepository = userRepository;
    }

    public void CreateUser(CreateUserInput input)
    {
        var user = new User
        {
            Name = input.Name,
            Surname = input.Surname,
            EmailAddress = input.EmailAddress,
            Password = input.Password
        };

        _userRepository.Insert(user);
    }
}

通过 new 一个新的实体去赋值并保存数据,User 实体在现实的应用程序中会有更多的属性,这样的手动创建它会变得乏味且容易出错。当我们想要向 User 和 CreateUserInput 添加新属性时,我们还必须更改映射代码。

上个例子繁琐,我们做出改进

我们可以使用一个库来自动处理我们的映射。 AutoMapper是对象到对象映射的最佳库之一。ASP.NET Boilerplate 定义了一个IObjectMapper 接口来抽象它,然后使用Abp.AutoMapper 包中的 AutoMapper 实现这个接口。

注意:需要将Abp.AutoMapper NuGet 包安装到您的项目中:
public class UserAppService : ApplicationService
{
    private readonly IRepository<User> _userRepository;
    private readonly IObjectMapper _objectMapper;

    public UserAppService(IRepository<User> userRepository, IObjectMapper objectMapper)
    {
        _userRepository = userRepository;
        _objectMapper = objectMapper;
    }

    public void CreateUser(CreateUserInput input)
    {
        var user = _objectMapper.Map<User>(input);
        _userRepository.Insert(user);
    }
}
IObjectMapper 是一个简单的抽象,它具有将一个对象映射到另一个对象的 Map 方法。
Map 是一个简单的方法,它获取源对象并创建一个新的目标对象,其类型声明为通用参数(本示例中的 User)。Map 方法具有将对象映射到现有对象的重载 。假设我们已经有一个 User 实体并且想要使用一个对象更新它的属性:
public void UpdateUser(UpdateUserInput input)
{
    var user = _userRepository.Get(input.Id);
    _objectMapper.Map(input, user);
}
大多数时候,您可能只想直接(和传统地)映射类。在这种情况下,您可以使用AutoMap、AutoMapFrom和AutoMapTo 属性。例如,如果我们想将CreateUserInput类映射到上面示例中的User类,我们可以使用AutoMapTo属性,如下所示:
[AutoMapTo(typeof(User))]
public class CreateUserInput
{
    public string Name { get; set; }

    public string Surname { get; set; }

    public string EmailAddress { get; set; }

    public string Password { get; set; }
}

自定义映射

在某些情况下,简单映射可能不适合。例如,两个类的属性名称可能略有不同,或者您可能希望在映射过程中忽略某些属性。在这种情况下,您应该直接使用 AutoMapper 的 API 来定义映射。Abp.AutoMapper 包定义了一个 API 来使自定义映射更加模块化。
假设我们想在映射时忽略密码,并且用户的电子邮件属性名称略有不同。我们可以定义映射如下所示:
[DependsOn(typeof(AbpAutoMapperModule))]
public class MyModule : AbpModule
{
    public override void PreInitialize()
    {
        Configuration.Modules.AbpAutoMapper().Configurators.Add(config =>
        {
            config.CreateMap<CreateUserInput, User>()
                  .ForMember(u => u.Password, options => options.Ignore())
                  .ForMember(u => u.Email, options => options.MapFrom(input => input.EmailAddress));
        });
    }
}

可以使用另一种变种类型:

[DependsOn(typeof(AbpAutoMapperModule))]
public class MyModule : AbpModule
{
    public override void PreInitialize()
    {
        
    }
    public override void Initialize()
    {
        var thisAssembly = typeof(MyModule ).GetAssembly();

        IocManager.RegisterAssemblyByConvention(thisAssembly);

        Configuration.Modules.AbpAutoMapper().Configurators.Add(
            cfg => cfg.AddProfile<CustomDtoMapperProfile>()
        );
    }
}

public class CustomDtoMapperProfile : Profile
{
     public CustomDtoMapperProfile()
     {
          CreateMap<CreateUserInput, User>()
                .ForMember(u => u.Password, options => options.Ignore())
                .ForMember(u => u.Email, options => options.MapFrom(input => input.EmailAddress));
     }
}


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK