Domanda

Nel domanda sulla utilità di IoC container, il mittente vincente ha detto che con un contenitore CIO si può prendere questo:

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 = value;
            _lastName = value;
            if(oldValue != value)
                OnPropertyChanged("LastName");
        }
    }
}

a questo:

var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper()); 

Domande:

  • contenitore che magia IoC fornisce questa bontà?
  • Un esempio l'attuazione del presente?
  • Le eventuali aspetti negativi?
  • In un progetto con dipendenze complesse, sarò in pianto quando cerco di applicare l'associazione dati a questi oggetti?
È stato utile?

Soluzione

Per il secondo frammento di codice al lavoro, NotifyPropertyChangedWrapper avrebbe certamente dovuto usare riflessione (o dynamic) per generare una classe che fornisce un'interfaccia compatibile con Customer e implementa la notifica di proprietà automatica. Non ci dovrebbe essere alcun dato problemi vincolanti, ma ci sarebbe un po 'in testa.

Un'implementazione semplificata che utilizza un oggetto dinamico potrebbe essere simile a questo:

public class NotifyPropertyChangedWrapper<T> 
    : DynamicObject, INotifyPropertyChanged
{
    private T _obj;

    public NotifyPropertyChangedWrapper(T obj)
    {
        _obj = obj;
    }

    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        result = typeof(T).GetProperty(binder.Name).GetValue(_obj);
        return true;
    }

    // If you try to set a value of a property that is
    // not defined in the class, this method is called.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        typeof(T).GetProperty(binder.Name).SetValue(_obj, value);
        OnPropertyChanged(binder.Name);
        return true;
    }

    // Implement OnPropertyChanged...
}

Ovviamente, qualsiasi codice che consuma uno di questi oggetti perderebbe qualsiasi tipo di sicurezza statica. L'altra possibilità è quella di generare una classe che implementa la stessa interfaccia classe essendo avvolta. Ci sono molti esempi di questo sul web. Il requisito principale è che il vostro Customer avrebbe dovuto essere sia una interface o avrebbe bisogno tutte le sue proprietà di essere virtuale.

Altri suggerimenti

Per fare questo in modo generico (cioè un unico pezzo di codice che implementa INotifyPropertyChanged per ogni classe) utilizzare un proxy. Ci sono un sacco di implementazioni in tutto per fare questo con Castle.DynamicProxy o < a href = "http://www.google.com/search?hl=en&q=linfu+INotifyPropertyChanged" rel = "nofollow"> Linfu o unità . Queste librerie procura avere un buon supporto in contenitori CIO, ad esempio DynamicProxy ha una buona integrazione con il Castello di Windsor e Unity intercettazione (o come si chiama) ha ovviamente una buona integrazione con il contenitore Unità.

Non ho mai usato, ma è possibile presumibilmente creare qualcosa di simile utilizzando PostSharp .

Se siete alla ricerca di una soluzione specifica per gli oggetti associabili auto-generazione si dovrebbe guardare PropertyChanged.Fody (in precedenza NotifyPropertyWeaver). Ciò riscrive le classi che implementano INotifyPropertyChanged di includere il codice di notifica. C'è un esempio sulla pagina GitHub.

A mio parere questo è più ordinato rispetto all'utilizzo della soluzione del contenitore CIO proposta. Tuttavia, si tratta di una specifica biblioteca per INotifyPropertyChanged vincolante in modo non è applicabile come una soluzione generale, come è stato oggetto di discussione nella tua domanda collegata.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top