如何使用 Mapster 创建可重复使用的映射配置文件?

Que*_*n3r 4 c# .net-core mapster .net-5

我有一个 .Net 5 Web Api 项目并想使用

地图大师 v7.2.0

以避免手动映射对象。以下代码显示了示例场景

  • 设置映射配置
  • 来自多个来源的地图
  • 映射到具有不同名称的字段

[ApiController]
[Route("[controller]")]
public class MyController : ControllerBase
{
    [HttpGet]
    public ActionResult<UsernameWithTodoTitle> Get()
    {
        TypeAdapterConfig<(User, Todo), UsernameWithTodoTitle>
            .NewConfig()
            .Map(dest => dest, src => src.Item1) // map everything from user
            .Map(dest => dest, src => src.Item2) // map everything from todo
            .Map(dest => dest.TodoTitle, src => src.Item2.Title); // map the special fields from todo
        
        var user = new User { Username = "foo", FieldFromUser = "x" };
        var todo = new Todo { Title = "bar", FieldFromTodo = "y" };
        
        var usernameWithTodoTitle = (user, todo).Adapt<(User, Todo), UsernameWithTodoTitle>();
        
        return Ok(usernameWithTodoTitle);
    }
}

public class User
{
    public string Username { get; set; }
    public string FieldFromUser { get; set; }
}

public class Todo
{
    public string Title { get; set; } // !! map this one to the TodoTitle field !!
    public string FieldFromTodo { get; set; }
}

public class UsernameWithTodoTitle
{
    public string Username { get; set; }
    public string TodoTitle { get; set; } // !! this one is special, is has a different name !!
    public string FieldFromUser { get; set; }
    public string FieldFromTodo { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

运行应用程序时,映射似乎可以正常工作

在此输入图像描述

我必须以这种方式设置配置,其他方法对我不起作用。但还有3件事需要解决

  • 在我看来,配置是错误的。它映射了待办事项中的所有内容并再次映射了特殊字段......所以它可能会循环多次?如果有多个具有不同名称的字段,这可能会变得昂贵
  • 我在控制器内创建了配置。如何创建全局注册一次的可重用映射配置文件类?
  • 当有映射配置文件时,这条线var usernameWithTodoTitle = (user, todo).Adapt<(User, Todo), UsernameWithTodoTitle>();对我来说看起来很混乱。更好的是var usernameWithTodoTitle = UsernameWithTodoTitle.Adapt((user, todo)) /* pass in as a tuple */因为它根据参数类型选择正确的映射配置文件

你们对如何创建这样的映射配置文件有什么想法吗?

Lux*_*ant 5

我用 Mapster 成功做到了。我所做的是

\n

Startup.cs

\n
public void ConfigureServices(IServiceCollection services)\n{\n   // Some other magical code\n\n   // Tell Mapster to scan this assambly searching for the Mapster.IRegister\n   // classes and execute them\n   TypeAdapterConfig.GlobalSettings.Scan(Assembly.GetExecutingAssembly());\n}\n
Run Code Online (Sandbox Code Playgroud)\n

像这样创建另一个类

\n
using Mapster;\n\nnamespace Your.Cool.Namespace\n{\n    public class MappingConfig : IRegister\n    {\n        public void Register(TypeAdapterConfig config)\n        {\n            // Put your mapping logic here\n            config\n                .NewConfig<MySourceType, MyDestinyType>()\n                .Map(dest => dest.PropA, src => src.PropB);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

关键部分是 using TypeAdapterConfig.GlobalSettings,它是 Mapster 用来保存 mappig 配置的静态公共单例。如果你按照杰克的建议去做,它将是一个全新的TypeAdapterConfig,而不是 Mapster 实际使用的,并且不会工作(至少对我来说不是)。

\n

在您的单元测试中,请记住也加载映射配置文件

\n
[AssemblyInitialize] // Magic part 1 ~(\xcb\x98\xe2\x96\xbe\xcb\x98~)\npublic static void AssemblyInitialization(TestContext testContext)\n{\n    // Magic part 2 (~\xcb\x98\xe2\x96\xbe\xcb\x98)~\n    TypeAdapterConfig.GlobalSettings.Scan(AppDomain.CurrentDomain.GetAssemblies());\n}\n
Run Code Online (Sandbox Code Playgroud)\n