2010-09-24 30 views
12

Tôi đang sử dụng bộ dịch vụ web của bên thứ 3 và tôi đã nhấn một hình nhỏ. Trước khi tôi tự tạo một phương thức sao chép từng thuộc tính từ nguồn đến đích, tôi nghĩ tôi sẽ hỏi ở đây để có một giải pháp tốt hơn.2 đối tượng, chính xác giống nhau (ngoại trừ không gian tên) C#

Tôi có 2 đối tượng, một trong những loại Customer.CustomerParty và một trong các loại Appointment.CustomerParty. Các đối tượng CustomerParty thực sự là thuộc tính và sub-oject giống hệt nhau. Nhưng tôi không thể đúc từ 1 đến khác.

Vì vậy, tôi cần tìm một người nhất định từ dịch vụ web. Tôi có thể làm điều đó bằng cách gọi Customer.FindCustomer (customerID) và nó trả về một đối tượng Customer.CustomerParty.

Tôi cần lấy người đó mà tôi đã tìm thấy và sau đó sử dụng chúng một vài dòng trong yêu cầu "CreateAppointment". Appointment.CreateAppointment lấy một đối tượng cuộc hẹn, và đối tượng cuộc hẹn có một đối tượng CustomerParty.

Tuy nhiên, đối tượng CustomerParty mà nó muốn thực sự là Appointment.CustomerParty. Tôi đã có một Customer.CustomerParty.

Xem ý tôi là gì? Bất kỳ đề xuất?

+3

Bởi vì các lớp học là từ không gian tên khác nhau nó có nghĩa rằng họ là hoàn toàn khác nhau từ CLR quan điểm. Đó là lý do tại sao bạn không thể đúc một cái khác. – uthark

Trả lời

7

Kịch bản này là phổ biến khi viết mẫu miền. Về cơ bản, bạn cần phải viết một dịch giả miền giữa hai đối tượng. Bạn có thể làm điều này theo một số cách, nhưng tôi khuyên bạn nên có một hàm tạo được ghi đè (hoặc một phương thức tĩnh) trong kiểu đích có kiểu dịch vụ và thực hiện ánh xạ. Vì chúng là hai loại CLR, bạn không thể trực tiếp truyền từ loại này sang cái khác. Bạn cần sao chép thành viên theo từng thành viên.

public class ClientType 
{ 
    public string FieldOne { get; set; } 
    public string FieldTwo { get; set; } 

    public ClientType() 
    { 
    } 

    public ClientType(ServiceType serviceType) 
    { 
     this.FieldOne = serviceType.FieldOne; 
     this.FieldTwo = serviceType.FieldTwo; 
    } 
} 

Hoặc

public static class DomainTranslator 
{ 
    public static ServiceType Translate(ClientType type) 
    { 
     return new ServiceType { FieldOne = type.FieldOne, FieldTwo = type.FieldTwo }; 
    } 
} 
+0

Tôi nghĩ tôi sẽ phải đi tuyến đường này. Không may StackOverflow sẽ không cho phép tôi upvote bài viết của bạn OpenID không hoạt động trên StackOverflow từ máy tính công việc của tôi - các trang web openid khác làm, chỉ cần không StackOverlow – Matt

+0

@Matt: Bạn nên biết rằng có là những cách đơn giản như các phương thức động mà không yêu cầu bạn phải tự viết mã bản đồ –

+0

Bạn cũng có thể ghi đè lên dàn diễn viên rõ ràng – Aren

1

Tôi đang sử dụng bộ một bên thứ 3 của webservices ...

Giả sử bạn không thể sửa đổi các lớp học, tôi không nhận thức được bất kỳ cách nào bạn có thể thay đổi hành vi truyền. Ít nhất, không có cách nào không xa, phức tạp hơn nhiều so với việc chỉ viết một hàm ánh xạ CustomerToAppointmentPartyTranslator() ... :)

Giả sử bạn đang sử dụng phiên bản C# (3.5, tôi tin?), đây có thể là một ứng cử viên tốt cho một số extension method.

12

Tại sao bạn không sử dụng AutoMapper? Sau đó, bạn có thể làm:

TheirCustomerPartyClass source = WebService.ItsPartyTime(); 

YourCustomerPartyClass converted = 
    Mapper.Map<TheirCustomerPartyClass, YourCustomerPartyClass>(source); 

TheirCustomerPartyClass original = 
    Mapper.Map<YourCustomerPartyClass, TheirCustomerPartyClass>(converted); 

Chừng nào các thuộc tính giống hệt nhau, bạn có thể tạo ra một bản đồ thực sự đơn giản như thế này:

Mapper.CreateMap<TheirCustomerPartyClass, YourCustomerPartyClass>(); 
Mapper.CreateMap<YourCustomerPartyClass, TheirCustomerPartyClass>(); 
+0

Tôi sẽ xem liệu chúng tôi có thể thêm điều này vào dự án của mình hay không. Không chắc chắn nếu nó là giá trị trên đầu vào thời điểm này, nhưng cảm ơn cho đề nghị. Tôi chắc chắn nó sẽ giải quyết vấn đề của tôi. Thật không may StackOverflow sẽ không cho phép tôi upvote bài viết của bạn. OpenID không hoạt động trên StackOverflow từ máy tính công việc của tôi - các trang web openid khác làm, không chỉ StackOverlow. – Matt

+0

@Matt - Hầu như không có phí. AutoMapper khá nhẹ. Chắc chắn đáng để đi. – GenericTypeTea

+0

Làm việc tuyệt vời cho tôi. Mapper.CreateMap (); Entities.CorporateDelayTracking.Delay convertedDelay = Mapper.Map (trì hoãn); – ScottLenart

0

Hai lớp học với chính xác cùng một chữ ký, trong hai không gian tên khác nhau, là hai lớp khác nhau. Bạn sẽ không thể chuyển đổi hoàn toàn giữa chúng nếu chúng không nói rõ cách chúng có thể được chuyển đổi từ cái này sang cái kia bằng cách sử dụng các toán tử ngầm hoặc ngầm.

Có một số điều bạn có thể thực hiện với tính năng tuần tự hóa. WCF DataContract lớp học ở một bên không phải là cùng một loại chính xác như DataContract ở phía bên kia; họ chỉ cần có chữ ký giống nhau và được trang trí giống hệt nhau. Nếu điều này đúng với hai đối tượng của bạn, bạn có thể sử dụng một DataContractSerializer để "chuyển đổi" các kiểu thông qua trang trí DataContract của chúng.

Nếu bạn có quyền kiểm soát việc triển khai lớp này hay lớp kia, bạn cũng có thể xác định toán tử ngầm hoặc rõ ràng để xác định cách lớp kia có thể được chuyển đổi thành của bạn. Điều này có thể sẽ chỉ trả về một tham chiếu mới về một bản sao sâu của đối tượng khác trong loại của bạn. Bởi vì đây là trường hợp, tôi sẽ định nghĩa nó là rõ ràng, để đảm bảo chuyển đổi chỉ được thực hiện khi bạn CẦN nó (nó sẽ được sử dụng trong trường hợp khi bạn cast một cách rõ ràng, chẳng hạn như myAppCustomer = (Appointment.CustomerParty)myCustCustomer;).

Thậm chí nếu bạn không kiểm soát một trong hai lớp, bạn có thể viết một phương pháp mở rộng hoặc lớp thứ ba, sẽ thực hiện chuyển đổi này.

1

Bạn đã xem thêm một toán tử chuyển đổi vào một trong các lớp miền để xác định một diễn viên rõ ràng. See the msdn documentation here.

Tận hưởng!

1

Một cách đơn giản và rất nhanh chóng lập bản đồ các loại được sử dụng phương pháp PropertyCopy<TTarget>.CopyFrom<TSource>(TSource source) từ thư viện MiscUtil như mô tả here:

using MiscUtil.Reflection; 

class A 
{ 
    public int Foo { get; set; } 
} 

class B 
{ 
    public int Foo { get; set; } 
} 

class Program 
{ 
    static void Main() 
    { 
     A a = new A(); 
     a.Foo = 17; 
     B b = PropertyCopy<B>.CopyFrom(a); 

     bool success = b.Foo == 17; // success is true; 
    } 
} 
Các vấn đề liên quan