Wow, ich kann nicht glauben, dass Joel so etwas befürworten würde:
var svc = new ShippingService(new ProductLocator(),
new PricingService(), new InventoryService(),
new TrackingRepository(new ConfigProvider()),
new Logger(new EmailLogger(new ConfigProvider())));
darüber:
var svc = IoC.Resolve<IShippingService>();
Viele Leute sind sich nicht bewusst, dass die Kette der Abhängigkeiten verschachtelt werden kann und es schnell unhandlich wird, sie manuell zu verdrahten. Selbst bei Fabriken lohnt sich die Verdoppelung des Codes einfach nicht.
IoC-Container können komplex sein, ja. Aber für diesen einfachen Fall habe ich gezeigt, dass es unglaublich einfach ist.
Okay, rechtfertigen wir das noch weiter. Nehmen wir an, Sie haben einige Entitäten oder Modellobjekte, die Sie an eine intelligente Benutzeroberfläche binden möchten. Diese intelligente Benutzeroberfläche (nennen wir sie Shindows Morms) möchte, dass Sie INotifyPropertyChanged implementieren, damit sie Änderungen verfolgen und die Benutzeroberfläche entsprechend aktualisieren kann.
"OK, das klingt gar nicht so schwer", und Sie beginnen zu schreiben.
Sie beginnen damit:
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime CustomerSince { get; set; }
public string Status { get; set; }
}
und enden mit este :
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;
}
Das ist ekelhafter Klempnercode, und ich behaupte, wenn man so einen Code von Hand schreibt Sie beklauen Ihren Kunden . Es gibt bessere, intelligentere Arbeitsmethoden.
Kennen Sie den Begriff "intelligenter arbeiten, nicht härter"?
Stellen Sie sich vor, ein kluger Kopf aus Ihrem Team kommt und sagt: "Es gibt einen einfacheren Weg"
Wenn Sie Ihre Immobilien virtuell machen (beruhigen Sie sich, das ist keine große Sache), können wir weben in dieser Eigenschaft Verhalten automatisch. (Dies wird AOP genannt, aber machen Sie sich keine Gedanken über den Namen, sondern konzentrieren Sie sich darauf, was es für Sie tun wird)
Je nachdem, welches IoC-Tool Sie verwenden, könnten Sie etwas tun, das wie folgt aussieht:
var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper());
Puff! All diese manuellen INotifyPropertyChanged BS werden nun automatisch für Sie generiert, und zwar für jeden virtuellen Property Setter des betreffenden Objekts.
Ist das Magie? YES ! Wenn Sie sich darauf verlassen können, dass dieser Code seine Aufgabe erfüllt, können Sie den ganzen Hokuspokus mit der Eigenschaftsumschreibung getrost auslassen. Sie haben geschäftliche Probleme zu lösen.
Einige andere interessante Anwendungen eines IoC-Tools für AOP:
- Deklarative und verschachtelte Datenbanktransaktionen
- Deklarativ & verschachtelt Arbeitseinheit
- Protokollierung
- Vor- und Nachbedingungen (Design by Contract)