Wow, không thể tin rằng Joel sẽ ủng hộ điều này:
var svc = new ShippingService(new ProductLocator(),
new PricingService(), new InventoryService(),
new TrackingRepository(new ConfigProvider()),
new Logger(new EmailLogger(new ConfigProvider())));
về điều này:
var svc = IoC.Resolve<IShippingService>();
Nhiều người không nhận ra rằng chuỗi phụ thuộc của bạn có thể được lồng vào nhau và nó nhanh chóng trở nên khó sử dụng để kết nối chúng theo cách thủ công. Ngay cả với các nhà máy, việc sao chép mã của bạn cũng không đáng.
IoC container có thể phức tạp, vâng. Nhưng đối với trường hợp đơn giản này, tôi đã cho thấy nó cực kỳ dễ dàng.
Được rồi, hãy biện minh cho điều này nhiều hơn nữa. Giả sử bạn có một số thực thể hoặc đối tượng mô hình mà bạn muốn liên kết với giao diện người dùng thông minh. Giao diện người dùng thông minh này (chúng tôi sẽ gọi nó là Shindows Morms) muốn bạn triển khai INotifyPropertyChanged để nó có thể thay đổi theo dõi và cập nhật giao diện người dùng phù hợp.
"OK, điều đó không có vẻ quá khó" vì vậy bạn bắt đầu viết.
Bạn bắt đầu với điều này:
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime CustomerSince { get; set; }
public string Status { get; set; }
}
..và kết thúc với điều này :
public class UglyCustomer : INotifyPropertyChanged
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
string oldValue = _firstName;
_firstName = value;
if(oldValue != value)
OnPropertyChanged("FirstName");
}
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
string oldValue = _lastName;
_lastName = value;
if(oldValue != value)
OnPropertyChanged("LastName");
}
}
private DateTime _customerSince;
public DateTime CustomerSince
{
get { return _customerSince; }
set
{
DateTime oldValue = _customerSince;
_customerSince = value;
if(oldValue != value)
OnPropertyChanged("CustomerSince");
}
}
private string _status;
public string Status
{
get { return _status; }
set
{
string oldValue = _status;
_status = value;
if(oldValue != value)
OnPropertyChanged("Status");
}
}
protected virtual void OnPropertyChanged(string property)
{
var propertyChanged = PropertyChanged;
if(propertyChanged != null)
propertyChanged(this, new PropertyChangedEventArgs(property));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Đó là mã hệ thống ống nước kinh tởm, và tôi bảo đảm rằng nếu bạn viết mã như thế bằng tay thì bạn đang đánh cắp từ khách hàng của bạn . Có cách làm việc tốt hơn, thông minh hơn.
Bao giờ nghe thuật ngữ đó, làm việc thông minh hơn, không khó hơn?
Hãy tưởng tượng một số người thông minh trong nhóm của bạn đã đến và nói: "Đây là một cách dễ dàng hơn"
Nếu bạn thực hiện tài sản của bạn ảo (bình tĩnh xuống, nó không phải là lớn của một thỏa thuận), sau đó chúng ta có thể dệt ở chỗ hành vi sở hữu tự động. (Đây được gọi là AOP, nhưng đừng lo lắng về tên, hãy tập trung vào những gì nó sẽ làm cho bạn)
Tùy thuộc vào công cụ IoC nào bạn đang sử dụng, bạn có thể làm một cái gì đó trông như thế này:
var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper());
Gặp sự cố! Tất cả các hướng dẫn sử dụng INotifyPropertyChanged BS hiện được tạo tự động cho bạn, trên mọi trình thiết lập thuộc tính ảo của đối tượng được đề cập.
Đây có phải là phép thuật không? CÓ ! Nếu bạn có thể tin tưởng vào thực tế rằng mã này thực hiện công việc của nó, thì bạn có thể bỏ qua một cách an toàn tất cả các thuộc tính đó gói mumbo-jumbo. Bạn đã có vấn đề kinh doanh để giải quyết.
Một số cách sử dụng thú vị khác của công cụ IoC để thực hiện AOP:
- Giao dịch cơ sở dữ liệu khai báo & lồng nhau
- Đơn vị khai báo & lồng nhau
- Ghi nhật ký
- Điều kiện trước / đăng (Thiết kế theo hợp đồng)