2010-10-05 16 views
5

Trong dự án tôi đang làm việc, chúng tôi đang ánh xạ các DTO được tạo tự động cho các đối tượng kinh doanh. Cơ sở dữ liệu có một quy ước đặt tên khác thường (nhưng phần lớn là nhất quán), có nghĩa là có thể chuyển đổi hầu hết các tên thuộc tính DTO thành tên thuộc tính kinh doanh đối tượng tương đương của chúng, do đó tiết kiệm được nhiều dòng mã.Làm thế nào để tôi có được AutoMapper để đối phó với một quy ước đặt tên tùy chỉnh?

Ví dụ: trong DTO (và cơ sở dữ liệu), chúng tôi có một thuộc tính được gọi là account_ID__created sẽ ánh xạ tới thuộc tính BO được gọi là CreatedAccountId. Đây là loại chuyển đổi xảy ra trong MemberNameTransformer.GetBoMemberName(), do đó, nó không đơn giản như một quy ước hơi khác với một dấu tách khác nhau.

Sau những gì tôi đã có sẵn trong mã nguồn AutoMapper, tôi có điều này như đoán tốt nhất của tôi:

public class DtoBoMappingOptions : IMappingOptions 
{ 
    public INamingConvention SourceMemberNamingConvention 
    { 
     get { return new PascalCaseNamingConvention(); } 
     set { throw new NotImplementedException(); } 
    } 

    public INamingConvention DestinationMemberNamingConvention 
    { 
     get { return new PascalCaseNamingConvention(); } 
     set { throw new NotImplementedException(); } 
    } 

    public Func<string, string> SourceMemberNameTransformer 
    { 
     get { return s => s; } 
     set { throw new NotImplementedException(); } 
    } 

    public Func<string, string> DestinationMemberNameTransformer 
    { 
     get { return MemberNameTransformer.GetBoMemberName; } 
     set { throw new NotImplementedException(); } 
    } 
} 

Bây giờ, làm thế nào để nói với Mapper để sử dụng các tùy chọn này khi lập bản đồ SomeDto để SomeBusinessClass? Tôi nhận ra rằng tôi có thể có giao diện sai trong IMappingOptions. Thịt thực sự của những gì tôi đang cố gắng đạt được là trong MemeberNameTransformer.GetBoMemberName().

Tín dụng bổ sung: Làm cách nào để yêu cầu Người lập bản đồ sử dụng các tùy chọn này khi ánh xạ bất kỳ số nào ID tới IBusinessObject?

Trả lời

6

Nếu mọi thứ thực sự nhất quán, như textFirstName, bạn có thể sử dụng một số chức năng được tích hợp sẵn.

Mapper.Initialize(cfg => cfg.RecognizePrefixes(new[] { "text" })); 

Nếu không, bạn sẽ cần phải viết lớp riêng INamingConvention của bạn trông giống như thế này ..

class DTONaming : INamingConvention 
{ 

    #region INamingConvention Members 

    public string SeparatorCharacter 
    { 
     get { return string.Empty; } 
    } 

    public Regex SplittingExpression 
    { 
     get { return new Regex(""); } 
    } 

    #endregion 
} 

Sau đó, bạn có thể đăng ký rằng với automapper.

Mapper.Initialize(cfg => cfg.SourceMemberNamingConvention = new DTONaming()); 

Và AutoMapper sẽ sử dụng này cho bất kỳ ánh xạ, vì vậy nếu bạn cần phải hạn chế việc đăng ký của các tiền tố hoặc các đối tượng đặt tên tùy chỉnh bạn có thể cần phải khởi tạo và tái khởi tạo nó hoặc một cái gì đó. Tôi nghi ngờ kế hoạch đặt tên sẽ có hậu quả mặc dù.

Sửa

Với bổ sung gần đây của bạn, bạn sẽ sử dụng một SourceMemberNameTransformer để thay thế. Điều này cho phép bạn viết một hàm tự chuyển đổi tên.

Mapper.Initialize(cfg => cfg.SourceMemberNameTransformer = ConvertNames); 
private static string ConvertNames(string inputString) 
{ 
    var sections = inputString.Split('_'); 
    // transform the sections into w/e you need 
    return inputString; 
} 
+0

Tôi không nghĩ rằng điều này sẽ phù hợp với những gì tôi cần. Tôi đã cập nhật câu hỏi để phản ánh chính xác quy ước đặt tên mà tôi đang làm việc. Tôi thực sự cần Func để nói thành viên đích nào đến từ thành viên nguồn nào. –

+0

@Josh Kodroff kiểm tra câu trả lời cập nhật, tôi nghĩ rằng đó sẽ là những gì bạn cần. – Jab

+0

Đúng rồi! Tôi chỉ không thể tìm ra nơi để thiết lập SourceMemberNameTransformer. Bây giờ, tôi đang sử dụng Mapper trong nhiều lớp (DTO, BO, VM), vì vậy tôi không muốn sử dụng biến đó phổ biến. Bất kỳ ý tưởng về làm thế nào để đảm bảo rằng không xảy ra? –

Các vấn đề liên quan