2010-01-30 6 views
18

tôi có phương pháp này WCFWCF phụ thuộc tiêm và nhà máy trừu tượng

Profile GetProfileInfo(string profileType, string profileName) 

và một quy tắc kinh doanh:

nếu profileType là "A" đọc từ cơ sở dữ liệu.

nếu profileType là "B" được đọc từ tệp xml.

Câu hỏi đặt ra là: làm cách nào để triển khai nó bằng cách sử dụng vùng chứa tiêm phụ thuộc?

Trả lời

22

Hãy đầu tiên thừa nhận rằng bạn có một cái gì đó IProfileRepository như thế này:

public interface IProfileRepository 
{ 
    Profile GetProfile(string profileName); 
} 

cũng như hai triển khai: DatabaseProfileRepositoryXmlProfileRepository. Vấn đề là bạn muốn chọn đúng giá trị dựa trên giá trị của profileType.

Bạn có thể làm điều này bằng cách giới thiệu này Abstract Factory:

public interface IProfileRepositoryFactory 
{ 
    IProfileRepository Create(string profileType); 
} 

Giả sử rằng các IProfileRepositoryFactory đã được tiêm vào việc thực hiện dịch vụ, bây giờ bạn có thể thực hiện phương pháp GetProfileInfo như thế này:

public Profile GetProfileInfo(string profileType, string profileName) 
{ 
    return this.factory.Create(profileType).GetProfile(profileName); 
} 

Triển khai cụ thể của IProfileRepositoryFactory có thể trông giống như sau:

public class ProfileRepositoryFactory : IProfileRepositoryFactory 
{ 
    private readonly IProfileRepository aRepository; 
    private readonly IProfileRepository bRepository; 

    public ProfileRepositoryFactory(IProfileRepository aRepository, 
     IProfileRepository bRepository) 
    { 
     if(aRepository == null) 
     { 
      throw new ArgumentNullException("aRepository"); 
     } 
     if(bRepository == null) 
     { 
      throw new ArgumentNullException("bRepository"); 
     } 

     this.aRepository = aRepository; 
     this.bRepository = bRepository; 
    } 

    public IProfileRepository Create(string profileType) 
    { 
     if(profileType == "A") 
     { 
      return this.aRepository; 
     } 
     if(profileType == "B") 
     { 
      return this.bRepository; 
     } 

     // and so on... 
    } 
} 

Bây giờ bạn chỉ cần lấy container DI của bạn lựa chọn để dây nó tất cả lên cho bạn ...

+0

Chuỗi tuần tự 'ifs' có thể được thay thế bằng' chuyển/trường hợp 'nhanh hơn/dễ đọc hơn. Và 'profileType' thực sự phải là một kiểu liệt kê, không phải là một chuỗi tùy ý. Khác hơn đó là một câu trả lời tuyệt vời. :) – Aaronaught

+3

Có, không có bất đồng ở đó, nhưng tôi chỉ đi với API được đưa ra bởi OP :) –

+0

Bằng cách nào nó có thể thay đổi nếu tôi không biết tại thời gian biên dịch số lượng kho? Và nếu wcf của tôi chỉ có phụ thuộc với thư viện đăng nhập và các kho lưu trữ này, thì lựa chọn DI Container tốt nhất ở đâu? là MEF là sự lựa chọn tốt trong trường hợp này? – tartafe

4

Great câu trả lời của Mark, Tuy nhiên, giải pháp đưa ra không phải là Tóm tắt máy nhưng việc thực hiện các tiêu chuẩn Nhà máy mẫu. Vui lòng kiểm tra xem các lớp Marks phù hợp như thế nào trong sơ đồ UML mẫu nhà máy chuẩn. Click here to see above classes applied to Factory pattern UML

Vì trong mẫu nhà máy, nhà máy nhận thức được các lớp bê tông, chúng tôi có thể làm cho mã của ProfileRepositoryFactory đơn giản hơn nhiều như dưới đây. Vấn đề với việc tiêm các kho lưu trữ khác nhau vào nhà máy là bạn có nhiều thay đổi mã mỗi khi bạn thêm một loại bê tông mới. Với mã bên dưới, bạn chỉ cần cập nhật các công tắc để bao gồm lớp bê tông mới

 

    public class ProfileRepositoryFactory : IProfileRepositoryFactory 
    { 
     public IProfileRepository Create(string profileType) 
     { 
      switch(profileType) 
      { 
       case "A": 
        return new DatabaseProfileRepository(); 

       case "B": 
        return new XmlProfileRepository(); 
      } 
     } 
    } 
 

Abstract Factory là mẫu cao cấp hơn sử dụng để tạo các gia đình của các đối tượng có liên quan hoặc người phụ thuộc mà không quy định cụ thể các lớp bê tông của họ. Sơ đồ lớp UML có sẵn here giải thích rõ.