2016-03-08 28 views
5

Tôi đang sử dụng Microsoft Unity làm vùng chứa IoC của mình. Tôi có một số lớp mở rộng có thêm phương pháp hữu ích để doanh nghiệp của tôi đối tượng Đây là loại mã tôi sử dụng ngày hôm nay:Tiêm phụ thuộc cho các lớp mở rộng?

public static class BusinessObjectExtensions 
{ 
    public static bool CanDoStuff(this BusinessObject obj) 
    { 
     var repository = BusinessHost.Resolver.Resolve<IRepository>(); 
     var args = new EArgument { Name = obj.Name }; 
     return repository.AMethod(obj.UserName, args); 
    } 
} 

Có cách nào tốt hơn để quản lý dependency injection cho các lớp học mở rộng?

+0

tôi nghĩ rằng, Nó không cho thấy có bất kỳ yêu cầu để trở thành một 'mở rộng method' .. rất nhiều đối tượng phụ thuộc là – Moumit

Trả lời

2

Bạn thực sự nên cố gắng tránh extensionmethods trừ khi chúng chỉ hoạt động trên dữ liệu nội bộ (thuộc tính trong chính lớp), hoặc kiểu dữ liệu đơn giản được cung cấp trong phương thức. Bạn không nên nói chuyện với các phụ thuộc khác trong các phương pháp mở rộng của bạn. Nếu bạn làm theo quy tắc này, bạn không cần phải tiêm các lớp mở rộng với IoC của bạn cả.

+1

Đó là một điểm tốt. Có lẽ tôi nên tạo một lớp quản lý thay vì ... – Leonard

4

Cách mặc định thực tế của Dependency Injection bởi Constructor Injection là không thể cho các lớp tĩnh. Nó sẽ có thể sử dụng tham số tiêm như dưới đây, tuy nhiên đó không phải là một cách rất sạch sẽ.

public static class BusinessObjectExtensions 
{ 
    public static bool CanDoStuff(this BusinessObject obj, IRepository repository) 
    { 
     var args = new EArgument { Name = obj.Name }; 
     return repository.AMethod(obj.UserName, args); 
    } 
} 
1

Tại sao bạn làm điều đó?

Điều này làm tăng sự ghép nối trong ứng dụng của bạn lên mái nhà và có thể rất khó hiểu cho các đồng đội của bạn sử dụng phương pháp mở rộng (chúng phải lưu ý để tiêm kho mỗi lần sử dụng phương pháp này).

Thay vào đó, tạo ra một lớp riêng biệt và sử dụng constructor injection để tiêm IRepository dụ:

public class StuffExecuter  
{ 
    private readonly IRepository _repository; 

    public StuffExecuter(IRepository repository) 
    { 
     _repository = repository; 
    } 

    public bool CanExecute(BusinessObject obj) 
    { 
     _repository.Add(obj.UserName, new EArgument 
     { 
      Name = obj.Name 
     }); 
    } 
} 
+0

Đây là cách chúng tôi làm theo thiết kế, nhưng ví dụ trên được lấy từ trường hợp sử dụng thực sự cụ thể, nếu không hoàn toàn bị cô lập, trong đó chúng tôi tin vào sự tiện lợi của việc gắn các chức năng chúng tôi cần đối tượng kinh doanh của mình. Trong tầm nhìn, nó không phải là một ý tưởng tốt, vì vậy tôi sẽ di chuyển nó ở nơi khác. Cảm ơn bạn! – Leonard

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