Pregunta

En pregunta acerca de la utilidad de la COI de contenedores, el remitente mencionó que ganar con un contenedor IoC se puede tomar esto:

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 esto:

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

Preguntas:

  • contenedor que la magia COI ofrece esta bondad?
  • Un ejemplo implementar esto?
  • Cualquier desventajas?
  • En un proyecto con dependencias complejas, voy a estar llorando cuando intento de aplicar la unión a estos objetos de datos?
¿Fue útil?

Solución

Para su segundo fragmento de código para el trabajo, NotifyPropertyChangedWrapper sin duda tiene que utilizar la reflexión (o dynamic) para generar una clase que proporciona una interfaz compatible con Customer e implementa la notificación automática de la propiedad. No debería haber ningún dato temas vinculantes, pero habría una pequeña sobrecarga.

Una implementación simplificada que utiliza un objeto dinámico podría ser algo como esto:

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...
}

Obviamente, cualquier código que consume uno de estos objetos perdería ningún tipo de seguridad estática. La otra opción es generar una clase que implementa la misma interfaz que la clase está envolviendo. Hay muchos ejemplos de esto en la web. El requisito principal es que su Customer tendría que ser o bien un interface o que tendría que todas sus propiedades al ser virtual.

Otros consejos

Para hacer esto de una manera genérica (es decir, una sola pieza de código que implementa INotifyPropertyChanged para cualquier clase) utilizar un proxy. Hay un montón de implementaciones alrededor de hacer esto con Castle.DynamicProxy o < a href = "http://www.google.com/search?hl=en&q=linfu+INotifyPropertyChanged" rel = "nofollow"> Linfu o unidad . Estas bibliotecas de proxy tener un buen apoyo en contenedores IoC, por ejemplo DynamicProxy tiene una buena integración con el castillo de Windsor y la interceptación Unidad (o como se llame) tiene, evidentemente, una buena integración con el contenedor de la unidad.

Yo nunca he usado, pero que supuestamente puede crear algo como esto utilizando PostSharp .

Si usted está buscando una solución específica para la generación de objetos que pueden vincularse automáticamente que usted debe buscar en PropertyChanged.Fody (previamente NotifyPropertyWeaver). Este reescribe las clases que implementan INotifyPropertyChanged que incluyen el código de notificación. Hay un ejemplo en la página de GitHub.

En mi opinión, esto es más limpio que el uso de la solución de contenedores COI propuesto. Sin embargo, se trata de una biblioteca específica a INotifyPropertyChanged vinculante por lo que no es aplicable como una solución general, ya que se estaba discutiendo en su pregunta vinculada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top