首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Mapster创建可重用的映射配置文件?

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

Stack Overflow用户
提问于 2021-08-19 19:58:45
回答 4查看 3.1K关注 0票数 4

我有一个.Net 5 Web项目,希望使用

Mapster v7.2.0

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

configuration

  • map
  • 从多个源
  • 映射到不同名称的字段

代码语言:javascript
运行
复制
[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; }
}

在运行应用程序时,映射看起来很好。

我不得不以这种方式设置配置,其他方式对我无效。但还有三件事要解决

  • 在我看来配置不对。它把所有的东西都映射出来,然后再映射一个特殊的字段.所以它可能会循环多次?如果有多个名称不同的字段(
  • ),这可能会很昂贵,我在控制器中创建了配置。我如何创建一个可重用的映射配置文件类,一旦globally?
  • When有了映射配置文件,var usernameWithTodoTitle = (user, todo).Adapt<(User, Todo), UsernameWithTodoTitle>();就会非常混乱。最好是var usernameWithTodoTitle = UsernameWithTodoTitle.Adapt((user, todo)) /* pass in as a tuple */,因为它根据参数类型选择正确的映射配置文件

你们知道如何创建这样的映射配置文件吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-08-28 05:58:40

更新的:无法找到使用Mapster的方法,但是这里有一个使用Automapper的例子。

代码语言:javascript
运行
复制
using AutoMapper;
using System;

namespace ConsoleApp5
{
    class A { public string FirstName { get; set; } }

    public class B { public string Address1 { get; set; } }

    public class C
    {
        public string FirstName { get; set; }
        public string Address1 { get; set; }
    }

    public class DemoProfile : Profile
    {
        public DemoProfile()
        {
            CreateMap<(A, B), C>()
                .ForMember(dest=> dest.FirstName, opts => opts.MapFrom(src => src.Item1.FirstName))
                .ForMember(dest => dest.Address1, opts => opts.MapFrom(src => src.Item2.Address1));
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var config = new MapperConfiguration(cfg => {
                cfg.AddProfile<DemoProfile>();
            });

            var mapper = config.CreateMapper();
            var destination = mapper.Map<C>((new A {  FirstName = "Test" }, new B { Address1 = "Addr" }));

            Console.ReadKey();
        }
    }
}

嘿,我以前还没用过Mapster,但我收集到的是。关于您在(T1,T2)上使用(T1,T2)的元组类型,这是非常具体的,但是除了这件小事之外,我还能够在没有问题的情况下让它运行和映射。下面是一个小型控制台示例。

代码语言:javascript
运行
复制
using Mapster;
using System;

namespace ConsoleApp5
{
    class A { public string FirstName { get; set; } }

    public class B { public string Address1 { get; set; } }

    public class C
    {
        public string FirstName { get; set; }
        public string Address1 { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Option 1
            TypeAdapterConfig<Tuple<A, B>, C>.NewConfig()
                .Map(dest => dest.FirstName, src => src.Item1.FirstName)
                .Map(dest => dest.Address1, src => src.Item2.Address1);

            var destObject = new Tuple<A, B>(new A { FirstName = "Test" }, new B { Address1 = "Address 1" })
                .Adapt<Tuple<A, B>, C>();

            // Option 2
            TypeAdapterConfig<(A, B), C>.NewConfig()
                .Map(dest => dest.FirstName, src => src.Item1.FirstName)
                .Map(dest => dest.Address1, src => src.Item2.Address1);

            var destObject2 = (new A { FirstName = "Test" }, new B { Address1 = "Address 1" })
                .Adapt<(A, B), C>();

            Console.ReadKey();
        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 2021-12-24 15:49:51

您可以使用next:

代码语言:javascript
运行
复制
    var config = new TypeAdapterConfig()
    {
        RequireExplicitMapping = true,
        RequireDestinationMemberSource = true,
        Compiler = exp => exp.CompileFast()
    };

    config.Scan("Your assembly");

    services.AddSingleton(config);
    services.AddTransient<IMapper, ServiceMapper>();

    public class RegisterConfig : IRegister
    {
        public void Register(TypeAdapterConfig config)
        {
            config.NewConfig<TSource, TDestination>();
        }
    }

服务是IServiceCollection的地方

票数 0
EN

Stack Overflow用户

发布于 2022-10-06 18:50:01

我和Mapster一起做的。我所做的是

Startup.cs

代码语言:javascript
运行
复制
public void ConfigureServices(IServiceCollection services)
{
   // Some other magical code

   // Tell Mapster to scan this assambly searching for the Mapster.IRegister
   // classes and execute them
   TypeAdapterConfig.GlobalSettings.Scan(Assembly.GetExecutingAssembly());
}

创建像这样的另一个类

代码语言:javascript
运行
复制
using Mapster;

namespace Your.Cool.Namespace
{
    public class MappingConfig : IRegister
    {
        public void Register(TypeAdapterConfig config)
        {
            // Put your mapping logic here
            config
                .NewConfig<MySourceType, MyDestinyType>()
                .Map(dest => dest.PropA, src => src.PropB);
        }
    }
}

关键部分是使用TypeAdapterConfig.GlobalSettings,它是Mapster使用的静态公共单例,用于保存映射猪配置。如果你按杰克的建议去做,它将是一个复杂的新TypeAdapterConfig,而不是Mapster正在使用的那个,它不会起作用(至少对我来说不是这样)。

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

代码语言:javascript
运行
复制
[AssemblyInitialize] // Magic part 1 ~(˘▾˘~)
public static void AssemblyInitialization(TestContext testContext)
{
    // Magic part 2 (~˘▾˘)~
    TypeAdapterConfig.GlobalSettings.Scan(AppDomain.CurrentDomain.GetAssemblies());
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68853897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档