No conozco ninguna biblioteca que haga esto, pero podría escribir la suya con bastante facilidad.
Aquí está una base Toqué en unos pocos minutos que establece la unión entre dos propiedades simples datos de dos vías:
public static class Binder
{
public static void Bind(
INotifyPropertyChanged source,
string sourcePropertyName,
INotifyPropertyChanged target,
string targetPropertyName)
{
var sourceProperty
= source.GetType().GetProperty(sourcePropertyName);
var targetProperty
= target.GetType().GetProperty(targetPropertyName);
source.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
targetProperty.SetValue(target, sourceValue, null);
}
};
target.PropertyChanged +=
(s, a) =>
{
var sourceValue = sourceProperty.GetValue(source, null);
var targetValue = targetProperty.GetValue(target, null);
if (!Object.Equals(sourceValue, targetValue))
{
sourceProperty.SetValue(source, targetValue, null);
}
};
}
}
Por supuesto, este código le falta un par de sutilezas. Cosas que añadir incluyen
- Comprobación de que
source
y target
se asignan
- Comprobación de que las propiedades identificadas por
sourcePropertyName
y targetPropertyName
existen
- Comprobación de la compatibilidad tipo entre las dos propiedades
También, Reflejo es relativamente lento (aunque lo compara antes de descartarlo, no es que lento), por lo que es posible que desee utilizar compilado expresiones en su lugar.
Por último, dado que la especificación de propiedades por cadena es propensa a errores, podría usar expresiones Linq y métodos de extensión en su lugar. Entonces, en lugar de escribir
Binder.Bind(source, "Name", target, "Name")
se podría escribir
source.Bind(Name => target.Name);
En realidad, lo estaba preguntando porque estaba considerando escribir el mío. No quería reinventar la rueda y todo ... gracias. –
Actualización: he vinculado a mi biblioteca en la pregunta. –
Necesitaba una clase simple de enlace de datos barebone para mi proyecto actual en prisa, y el anterior casi se ajusta a lo que necesito. Acabo de reemplazar los nombres de propiedad usados con Reflection por dos delegados de Acción en los que obtengo/configuro desde POCO y aplico transformaciones y formateo. Definitivamente le daré una buena oportunidad a Truss en un próximo proyecto, porque realmente me resulta interesante. – Larry