2013-05-06 22 views
13

Hiện tại tôi đang thử nghiệm một chút với các thùng chứa phụ thuộc, lần này với Unity.Dependency Injection và các thông số hàm tạo khác - thực hành không tốt?

Với giao diện sau:

public interface IPodcastCommService 
{ 
    void Download(); 

    void Upload(); 
} 

và thực hiện như sau:

public class PodcastService 
{ 
    private IPodcastCommService commservice; 
    private String url; 

    public PodcastService(String url, IPodcastCommService commservice) 
    { 
     this.commservice = commservice; 
     this.url = url; 
    } 
} 

Bởi vì các nhà xây dựng, tôi đang tìm kiếm một giải pháp để vượt qua các tham số cho nó và tìm thấy nó:

var p = container.Resolve<IPodcastCommService>(new ParameterOverride("url", myUrl)); 

Cho đến giờ rất tốt, nhưng đồng thời tôi đọc về mức độ tồi tệ của nó và cách thức xấu thiết kế của lớp là có và có, nó trông một chút xấu xí. Nhưng làm thế nào tôi có thể vượt qua một tham số đến lớp một cách thanh lịch?

Suy nghĩ đầu tiên của tôi là làm tài sản đó, nhưng sau đó tôi phải kiểm tra mỗi khi tôi cần Url mà nó đã được cung cấp.

Cập nhật: Một ví dụ, nơi tôi đọc rằng đây là thiết kế xấu, là thế này:

Nhưng có thể có trường hợp bạn có vượt qua trong các thông số nhà xây dựng tùy chỉnh cho các hoạt động quyết tâm. Một số người có thể lập luận rằng tiếng hét của kiến ​​trúc xấu này nhưng có những tình huống như đưa một thùng chứa DI vào một hệ thống cũ có thể yêu cầu những loại hành động này.

Nguồn: http://mikaelkoskinen.net/unity-passing-constructor-parameters-to-resolve/

+1

bạn có thể cho tôi biết nơi bạn có màu đỏ vì đây là thiết kế tồi không? Bởi vì tôi thực sự nghĩ rằng thiết kế này là tốt nhất bạn sẽ nhận được. – Egi

+0

@Egi: Tôi đã cập nhật câu hỏi của mình bằng nguồn. – Kai

+0

Bạn có thể sử dụng [ServiceLocator] (https://commonservicelocator.codeplex.com/) để thực hiện DI mà không liệt kê các thuộc tính được chèn vào trong hàm tạo. – orad

Trả lời

3

Tôi không hiểu tại sao bạn cần PodcastService với bố cục IPodcastCommService, thay vì triển khai IPodcastCommService và có url được chèn bằng chuỗi. Tôi không hiểu tại sao thiết kế của bạn lại tệ. Tiêm url là IMHO tốt.

Nếu bạn nghĩ về một cách tốt hơn, tôi nghĩ rằng nó có thể được thay thế bằng cách tiêm một ngữ cảnh/cấu hình thay vì kiểu dữ liệu gốc.

public class PodcastService 
{ 
    private IPodcastCommService commservice; 
    private IConnectionContext connection; 

    public PodcastService(IConnectionContext connection, IPodcastCommService commservice) 
    { 
     this.commservice = commservice; 
     this.connection= connection; 
    } 
} 

public interface IConnectionContext{ 
    string PodcastServiceUrl{get;} 
} 

Nhưng một lần nữa, tôi không tìm thấy bất kỳ lợi ích nào từ nó (ngoại trừ bạn có thể xử lý phiên/hằng số/trường tĩnh) từ cách tiếp cận thông thường.

UPDATE:

Tôi đã tìm thấy câu hỏi tương tự về thiết kế xấu here. Tóm lại, nó không phải là tham số kiểu gốc (chuỗi, vv) hoặc tham số hàm tạo tùy chỉnh là xấu. Nó chỉ là bạn cần đặt tham số vào một lớp thực sự chịu trách nhiệm cho tham số. Và tham số hàm tạo tùy chỉnh sẽ là cần thiết nếu bạn xử lý một điều kiện if-else bên trong một mẫu nhà máy trừu tượng.

-3

Nó phụ thuộc vào khuôn khổ yu đang sử dụng. Ví dụ asp.net mvc nhà cung cấp tích hợp điểm cho IoC container như DependecyResolver. Bạn nên đặt tất cả các logic của bạn để xây dựng các đối tượng và tiêm phụ thuộc ở đó. Nếu bạn đang sử dụng aps.net, bạn có thể có một số loại trang cơ sở của preinit eevnt injects dependencies. Bạn không thể sử dụng tiêm constructor với asp.net, chỉ tiêm tài sản. Với winforms bạn có thể sử dụng một số loại hình thức nhà máy để xây dựng các đối tượng hình thức.

1

Trong trường hợp của bạn, tôi nghĩ DI thông qua hàm tạo là hoàn toàn ổn. Lý do tại sao nó được coi là một cách tiếp cận tốt hơn để đi qua các thuộc tính là bởi vì nó tốt hơn cho khả năng đọc, tức là tưởng tượng những gì constructor của bạn sẽ trông như thế nào nếu bạn đã phải tiêm 20 tài sản.

Nếu bạn chỉ có ý định tiêm một vài tài sản thì hoàn toàn không có hại là làm những gì bạn đang làm. Tôi sẽ xem xét chuyển sang một cách tiếp cận thuộc tính kiểu nếu bạn thấy phụ thuộc của bạn bắt đầu leo ​​lên.

+2

Nếu có nhiều hơn một vài lần tiêm, bạn có thể sử dụng mẫu 'Builder' để đơn giản hóa khả năng đọc. Tôi nghĩ rằng điều này là tốt hơn nhiều so với việc sử dụng các thuộc tính nếu đối tượng * yêu cầu * các thuộc tính được thiết lập trước khi nó có thể được sử dụng. –

+2

nếu hàm tạo của bạn có 20 đối số, tôi sẽ đặt cược rằng lớp của bạn làm hỏng SRP và nên được cấu trúc lại thành các lớp nhỏ hơn thay vì lạm dụng tính năng tiêm tài sản để dễ đọc hơn! tài sản tiêm trong quan điểm của tôi là tốt nếu bạn cần hành vi năng động mà sẽ có thể thay đổi trong thời gian chạy. – Egi

1

Có lẽ một

container.RegisterType<PodcastService>(new InjectionConstructor("myUrlParameter")); 

sẽ làm tốt hơn, phải không?

nhưng nếu bạn cần nhiều hơn thì một dịch vụ podcast và họ cần một url khác, tham số ghi đè là ok tôi đoán.

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