### [NuGetPackage] 使用 Mapster 處理物件對應

Install-Package Mapster

１．兩個屬性名稱相同的物件轉換

    public class ClassA
{
public int Id { get; set; }

public string Name { get; set; }

public decimal Price { get; set; }

public string Count { get; set; }
}

public class ClassB
{
public int Id { get; set; }

public string Name { get; set; }

public decimal Price { get; set; }
}

public void BasicConvert()
{
var classA = new ClassA()
{
Id = 123,
Name = "",
Price = 23.3m
};

classB.Should().BeEquivalentTo(new ClassB()
{
Id = 123,
Name = "",
Price = 23.3m
});
}

２．屬性名稱相同但型別不同的物件

    public class ClassA
{
public int Id { get; set; }

public string Name { get; set; }

public decimal Price { get; set; }

public string Count { get; set; }
}

public class ClassC
{
public string Id { get; set; }

public string Name { get; set; }

public string Price { get; set; }

public int Count { get; set; }
}

public void BasicConvert_Type_Not_Same()
{
var classA = new ClassA()
{
Id = 123,
Name = "",
Price = 23.3m,
Count = "3",
};

classC.Should().BeEquivalentTo(new ClassC()
{
Id = "123",
Name = "",
Price = "23.3",
Count = 3,
});
}

３．從字典轉換為物件

    public class ClassA
{
public int Id { get; set; }

public string Name { get; set; }

public decimal Price { get; set; }

public string Count { get; set; }
}

public void BasicConvert_Dictionary()
{
var dictionary = new Dictionary<string, string>()
{
{ "Id", "1" },
{ "Name", "Test" }
};

classA.Should().BeEquivalentTo(new ClassA()
{
Id = 1,
Name = "Test"
});
}

４．集合的轉換

    public class ClassA
{
public int Id { get; set; }

public string Name { get; set; }

public decimal Price { get; set; }

public string Count { get; set; }
}

public class ClassB
{
public int Id { get; set; }

public string Name { get; set; }

public decimal Price { get; set; }
}

public void BasicConvert_List()
{
var classAs = new List<ClassA>()
{
new ClassA(){Id = 1,Name = "Test"},
new ClassA(){Id = 2,Name = "Test2"},
};

classBs.Should().BeEquivalentTo(new List<ClassB>()
{
new ClassB() { Id = 1, Name = "Test" },
new ClassB() { Id = 2, Name = "Test2" },
});
}

５．從靜態類別自定義轉換邏輯

    public void CustomConvert()
{
.NewConfig()
.Ignore(b => b.Price)
.Map(b => b.Name, a => $"{a.Id}_{a.Name}"); var classA = new ClassA() { Id = 1, Name = "Test", Price = 12.34m }; var classB = classA.Adapt<ClassB>(); classB.Should().BeEquivalentTo(new ClassB() { Id = 1, Name = "1_Test", Price = 0m, }); } ６．包含子物件的物件轉換  public class ClassD { public int Id { get; set; } public ClassB ClassB { get; set; } } public class ClassB { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } public class MyClassA { public int Id { get; set; } public MyClassB ClassB { get; set; } } public class MyClassB { public int Id { get; set; } public string Name { get; set; } } public void InnerClass() { TypeAdapterConfig<ClassB, MyClassB>.ForType(); var classD = new ClassD { Id = 1, ClassB = new ClassB { Id = 2, Name = "Test", Price = 23m } }; var myClassA = classD.Adapt<MyClassA>(); myClassA.Should().BeEquivalentTo(new MyClassA() { Id = 1, ClassB = new MyClassB() { Id = 2, Name = "Test" } }); } ７．從instance config自定義轉換邏輯  public class ClassA { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Count { get; set; } } public class ClassB { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } public void Basic() { var config = new TypeAdapterConfig(); config.NewConfig<ClassA,ClassB>() .Map(b=>b.Id,a=>a.Id+1) .Map(b=>b.Name,a=>"Name"); var classA = new ClassA() { Id = 1, Name = "Test" }; var classB = classA.Adapt<ClassB>(config); classB.Should().BeEquivalentTo(new ClassB() { Id = 2, Name = "Name" }); }  ８．從ASP.NET Core DI框架注入 Install-Package Mapster.DependencyInjection Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddSingleton(GetAdapterConfig()); services.AddScoped<IMapper, ServiceMapper>(); } private TypeAdapterConfig GetAdapterConfig() { var config = new TypeAdapterConfig(); config.NewConfig<ClassA, ClassB>() .Map(b => b.Name, a =>$"{a.Id}_{a.Price}");

config.NewConfig<ClassB, ClassC>()
.Ignore(c => c.Name)
.Map(c => c.Id, b => b.Id + 2);

return config;
}

９．注入使用

Controller

public HomeController(IMapper mapper)
{
_mapper = mapper;
}

public string Index()
{
var classA = new ClassA()
{
Id = 1,
Name = "Test",
Price = 12.34m
};
var classB = _mapper.Map<ClassB>(classA);

return JsonConvert.SerializeObject(classB);
}

public string Index2()
{
var classA = new ClassB()
{
Id = 1,
Name = "Test",
Price = 12.34m
};
var classC = _mapper.Map<ClassC>(classA);

return JsonConvert.SerializeObject(classC);
}

Method Mean StdDev Error Gen 0 Gen 1 Gen 2 Allocated
'Mapster 5.0.0' 141.84 ms 0.931 ms 1.408 ms 31250.0000 - - 125.12 MB
'Mapster 5.0.0 (Roslyn)' 60.48 ms 1.186 ms 1.993 ms 31222.2222 - - 125.12 MB
'Mapster 5.0.0 (FEC)' 58.17 ms 0.231 ms 0.442 ms 29714.2857 - - 119.02 MB
'Mapster 5.0.0 (Codegen)' 51.56 ms 0.312 ms 0.524 ms 31200.0000 - - 125.12 MB
'ExpressMapper 1.9.1' 299.05 ms 2.081 ms 3.146 ms 60000.0000 - - 241.85 MB
'AutoMapper 9.0.0' 708.06 ms 3.398 ms 5.137 ms 91000.0000 - - 364.69 MB