AutoMapper vs ValueInjecter [đã đóng]


209

Mỗi khi tôi tìm kiếm nội dung AutoMapper trên StackOverflow, tôi đang đọc một cái gì đó về ValueInjecter .

Ai đó có thể cho tôi biết những ưu và nhược điểm giữa chúng (hiệu suất, tính năng, sử dụng API, khả năng mở rộng, thử nghiệm) không?


2
Một cái khác tôi thấy đề cập rất nhiều là EmitMapper .
adrianbanks

1
Còn keo thì sao? keo.codeplex.com Trông giống như một dự án tuyệt vời, nhưng tôi chưa thử nó. Tôi sẽ trong tháng tới mặc dù. Tôi cũng đã thấy một dự án có tên EmitMapper emitmapper.codeplex.com
Trygve

Xem một bài viết nói về hai công cụ đó - devproconnections.com/development/,
George Birbilis

Câu trả lời:


170

Là người tạo ra ValueInjecter , tôi có thể nói với bạn rằng tôi đã làm điều đó bởi vì tôi muốn một cái gì đó đơn giản và rất linh hoạt

Tôi thực sự không thích viết nhiều hoặc viết nhiều monkey codenhư:

Prop1.Ignore, Prop2.Ignore etc.
CreateMap<Foo,Bar>(); CreateMap<Tomato, Potato>(); etc.

ValueInjecter giống như mozilla với các plugin của nó, bạn tạo ValueInjections và sử dụng chúng

có các mũi tiêm tích hợp để làm phẳng, không làm phẳng và một số được dự định sẽ được thừa kế

và nó hoạt động nhiều hơn theo kiểu khía cạnh , bạn không phải chỉ định tất cả các thuộc tính 1-1, thay vào đó bạn làm một cái gì đó như:

lấy tất cả các thuộc tính int từ nguồn có tên kết thúc bằng "Id", biến đổi giá trị và đặt từng thuộc tính vào một thuộc tính trong đối tượng nguồn có cùng tên mà không có hậu tố Id và kiểu này được kế thừa từ Thực thể, đại loại như thế

Vì vậy, một sự khác biệt rõ ràng, ValueInjecter được sử dụng ngay cả trong các hình thức cửa sổ với việc làm phẳng và không làm phẳng, đó là cách nó linh hoạt

(ánh xạ từ đối tượng để điều khiển biểu mẫu và trở lại)

Automapper, không thể sử dụng trong các hình thức cửa sổ, không bỏ qua, nhưng nó có những thứ tốt như ánh xạ bộ sưu tập, vì vậy trong trường hợp bạn cần nó với ValueInjecter, bạn chỉ cần làm một cái gì đó như:

foos.Select(o => new Bar().InjectFrom(o));

bạn cũng có thể sử dụng ValueInjecter để ánh xạ từ các đối tượng ẩn danhđộng

sự khác biệt:

  • automapper tạo cấu hình cho từng khả năng ánh xạ CreateMap ()

  • valueinjecter tiêm từ bất kỳ đối tượng nào vào bất kỳ đối tượng nào (cũng có trường hợp khi bạn tiêm từ đối tượng sang valuetype)

  • automapper đã làm phẳng nó, và chỉ cho các loại đơn giản hoặc cùng loại, và nó không có kết cấu

  • valueinjecter chỉ khi bạn cần nó, bạn làm target.InjectFrom<FlatLoopValueInjection>(source); also <UnflatLoopValueInjection> và nếu bạn muốn từ Foo.Bar.Name of type Stringđể FooBarName of type Class1bạn kế thừa FlatLoopValueInjection và chỉ định này

  • automapper ánh xạ các thuộc tính có cùng tên theo mặc định và đối với phần còn lại, bạn phải chỉ định từng cái một và làm các công cụ như Prop1.Ignore (), Prop2.Ignore (), v.v.

  • valueinjecter có một mặc định tiêm .InjectFrom () thực hiện các thuộc tính có cùng tên và loại; đối với mọi thứ khác, bạn tạo các giá trị tùy chỉnh của mình với logic / quy tắc ánh xạ riêng lẻ, giống như các khía cạnh hơn, ví dụ: từ tất cả các đạo cụ của Type Foo đến tất cả các đạo cụ của loại Bar


5
Đối với vị thần tình yêu, xin vui lòng cho tôi biết ValueInjection có thể lấy một đồ thị sâu ViewModel và ánh xạ tới / từ một đồ thị sâu Thực thể kinh doanh và ánh xạ mọi thứ giống hệt nhau mà không cần làm việc và tôi chỉ cần xác định cách xử lý những gì khác nhau. Tôi đã hy vọng AutoMapper sẽ bổ sung khả năng này nhưng nó chưa bao giờ thành hiện thực và tôi đã không có thời gian để viết trình ánh xạ tự động của riêng mình.
Chris Marisic

3
@Chris Marisic bạn có thể sử dụng nó để làm điều đó, trong trường hợp bạn có nghĩa là nhân bản sâu, tôi đã thực hiện một lần tiêm một cách tương tự nhưng nó không hoạt động cho các bộ sưu tập thuộc tính valueinjecter.codeplex.com/Thread/View.aspx?ThreadId=236126 hoặc bạn có thể thực hiện một ViewModel phẳng và sử dụng làm phẳng và không làm phẳng, điều này sẽ dễ dàng
Omu

Các thực thể ViewModel và tên miền sẽ tương tự nhưng khác nhau, vì vậy không phải là một bản sao thuần túy. 90% thuộc tính thường là loại và tên chính xác, ViewModels thường kết thúc với SelectLists và những thứ bị ràng buộc với chúng mà tôi muốn bỏ qua khi quay lại miền. Cả hai rất có khả năng có bộ sưu tập các đối tượng trên chúng mặc dù.
Chris Marisic

27
<pedant>Trông thật tuyệt, nhưng có lẽ nó phải là ValueInjectOr? </pedant>
Craig Stuntz

1
nhưng vì lý do nào đó nó er :)
Omu

59

Vì tôi chưa bao giờ sử dụng bất kỳ công cụ nào khác, tôi chỉ có thể nói về AutoMapper. Tôi đã có một vài mục tiêu trong việc xây dựng AutoMapper:

  • Hỗ trợ làm phẳng các đối tượng DTO câm
  • Hỗ trợ các kịch bản rõ ràng ngoài hộp (bộ sưu tập, bảng liệt kê, v.v.)
  • Có thể dễ dàng xác minh ánh xạ trong một thử nghiệm
  • Cho phép các trường hợp cạnh để giải quyết các giá trị từ các vị trí khác (ánh xạ loại tùy chỉnh-> kiểu ánh xạ, ánh xạ thành viên riêng lẻ và một số trường hợp cạnh thực sự điên rồ).

Nếu bạn muốn làm những điều này, AutoMapper hoạt động rất tốt cho bạn. Những điều AutoMapper không làm tốt là:

  • Làm đầy các đối tượng hiện có
  • Không làm phẳng

Lý do là tôi không bao giờ cần phải làm những điều này. Đối với hầu hết các phần, các thực thể của chúng tôi không có setters, không để lộ các bộ sưu tập, vv vì vậy đó là lý do tại sao nó không có ở đó. Chúng tôi sử dụng AutoMapper để làm phẳng các DTO và ánh xạ từ các mô hình UI để ra lệnh cho các thông báo và những thứ tương tự. Đó là nơi nó hoạt động thực sự, thực sự tốt cho chúng tôi.


1
@Jimmy Bogard Bạn có thấy rằng việc lấp đầy các đối tượng hiện có sẽ đưa nó vào danh sách tính năng cho AutoMapper không?
La Mã

Tôi chưa thử ValueInjecter, nhưng với những gì chúng tôi cần, automapper rất mạnh.
richb01

Tôi nghĩ rằng điều quan trọng nhất ở đây là tính xác minh. Khi đổi tên và tái cấu trúc mọi thứ, đây là một sự trợ giúp rất lớn.
Kugel

55

Tôi đã thử cả hai và thích ValueInjecter vì nó rất đơn giản:

myObject.InjectFrom(otherObject);

Đó là tất cả những gì cần biết cho phần lớn nhu cầu tiêm của tôi. Nó không thể đơn giản và thanh lịch hơn thế này.


1
this objectPhương pháp mở rộng có?
Chris Marisic

2
Làm cách nào tôi có thể tách mã của mình khỏi ValueInjecter? Đối với tôi, dường như luôn có một sự phụ thuộc vào ValueInjecter tức là trong dự án web của tôi, bởi vì tôi sử dụng ValueInjecter (phương thức mở rộng) trên đối tượng đã cho TRỰC TIẾP.
Rookian

1
@Rookian thành thật đây không phải là một mối quan tâm bạn nên suy nghĩ quá nhiều. Bạn có thể phụ thuộc vào giao diện như @Omu đã đề cập, vì vậy nếu bạn thay đổi người lập bản đồ, bạn có thể tiết kiệm một số công việc (có thể không nhiều). Kiểu phụ thuộc này quá khó để trừu tượng trừ khi bạn muốn tham gia vào AOP đầy đủ, điều không may là nhiều lần không thể hoàn tác vì .NET không giúp cung cấp hỗ trợ AOP một cách chính xác. Bây giờ bạn có thể loại bỏ một số ánh xạ, đặc biệt nếu bạn sử dụng MVC và viết Bộ lọc hành động xử lý ánh xạ ViewModel / DomainModel.
Chris Marisic

13
Tại sao một bọc là giải pháp tốt nhất? Điều duy nhất bạn cần làm nếu bạn muốn chuyển đổi trình ánh xạ là tự mình thực hiện InjectFrom()phương thức mở rộng.
jgauffin

1
Tôi cũng đã thử cả hai và tôi thích AutoMapper hơn. Tôi đã sử dụng nó cho một phần nhỏ trong hệ thống của mình, nơi tôi ánh xạ các Thực thể với các lớp được tạo Linq2Sql. Ánh xạ đơn giản như StockTotalQuantity -> stock_size_quantity hoặc UserId -> user_id đã hoạt động với AutoMapper theo mặc định. Nó không hoạt động với ValeInjecter ngay cả sau khi thêm tham vọng. Bám sát AutoMapper ngay bây giờ.
Artur Kędzior

27

Đây là một câu hỏi tôi đã nghiên cứu quá, và đối với trường hợp sử dụng của tôi, nó dường như là người đánh giá cao. Nó không yêu cầu thiết lập trước để sử dụng (có thể đạt hiệu suất tôi đoán, mặc dù nếu được triển khai một cách thông minh, nó có thể lưu trữ ánh xạ cho các yêu cầu trong tương lai thay vì phản ánh mỗi lần), vì vậy bạn không cần phải xác định trước bất kỳ ánh xạ nào trước khi sử dụng chúng.

Quan trọng nhất, tuy nhiên, nó cho phép ánh xạ ngược. Bây giờ tôi có thể đang thiếu một cái gì đó ở đây vì Jimmy đề cập rằng anh ta thấy không có trường hợp sử dụng nào cần thiết, vì vậy có lẽ tôi đã nhầm mẫu, nhưng trường hợp sử dụng của tôi là tôi đang tạo một đối tượng ViewModel từ ORM của mình. Sau đó tôi hiển thị điều này trên trang web của tôi. Khi người dùng kết thúc, tôi lấy lại ViewModel dưới dạng một pppppost, làm thế nào để nó được chuyển đổi trở lại các lớp ORM ban đầu? Tôi muốn biết mô hình với automapper. Với ValueInjection, nó là tầm thường và thậm chí nó sẽ không được làm phẳng. ví dụ: Tạo một thực thể mới

Mô hình được tạo bởi entityframework (mô hình đầu tiên):

public partial class Family
{ 
    public int Id { get; set; }
    public string FamilyName { get; set; }

    public virtual Address Address { get; set; }
}

public partial class Address
{
    public int Id { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string TownCity { get; set; }
    public string County { get; set; }
    public string Postcode { get; set; }

    public virtual Family Family { get; set; }
}

ViewModel (mà tôi có thể trang trí với trình xác nhận):

public class FamilyViewModel
{
    public int Id { get; set; }
    public string FamilyName { get; set; }

    public int AddressId { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string AddressTownCity { get; set; }
    public string AddressCounty { get; set; }
    public string AddressPostcode { get; set; }
}

ViewContoder:

    //
    // GET: /Family/Create

    public ActionResult Create()
    {
        return View();
    } 

    //
    // POST: /Family/Create

    [HttpPost]
    public ActionResult Create(FamilyViewModel familyViewModel)
    {
        try
        {
            Family family = new Family();
            family.InjectFrom<UnflatLoopValueInjection>(familyViewModel);
            db.Families.Add(family);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

Theo suy nghĩ của tôi, nó không đơn giản hơn thế nhiều sao?

(Vì vậy, điều này đặt ra câu hỏi, có gì sai với mẫu mà tôi gặp phải (và có vẻ như nhiều người khác làm vậy), rằng nó không được coi là có giá trị đối với AutoMapper?)

Tuy nhiên, nếu mẫu này là đã được đăng ký, là mẫu bạn muốn sử dụng, thì phiếu bầu của tôi là giá trị tính theo dặm quốc gia.


1
có lẽ bạn cũng nên hỏi điều này trong một câu hỏi riêng được gắn thẻ asp.net-mvc và các cách thực hành tốt nhất, ViewModel ..., atm Tôi không thấy bất kỳ vấn đề nào miễn là nó hoạt động tốt cho bạn, nhưng tôi chắc chắn rằng ai đó có thể có ý kiến ​​khác nhau
Omu

Cũng đã học được nhiều mvc. Bây giờ tôi có thể trả lời câu hỏi của tôi. Cách để cập nhật mô hình ban đầu khi bạn lấy lại mô hình chế độ xem được điền, là sử dụng hàm UpdateModel () mvc cung cấp.
DanH

1
UpdateModel () được sử dụng để điền vào Mô hình đại diện cho chế độ xem và giống như thực hiện Hành động (mô hình MyModelClasss)
Omu

Đúng, nhưng nếu bạn muốn có một mô hình khung nhìn riêng biệt, ví dụ như một mô hình lưu trữ, thì nó có thể được sử dụng để đưa ra giả định rằng ánh xạ là tầm thường (và nó thường là). Tất nhiên, nếu ValueInjection phức tạp hơn xuất hiện.
DanH

1
Tôi nghĩ rằng đối số có thể được đưa ra là bạn không nên đơn giản đặt lại các thuộc tính của mình trên mô hình miền - bạn nên sử dụng các phương thức thêm ý nghĩa cho nó.
Mike Cole
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.