Gracias che, me pongo colorado.... :))
Daniel El día 19/11/07, Leandro Tuttini <[EMAIL PROTECTED]> escribió: > > > Daniel, que tal. > > La verdad te pasaste, el codigo esta genial. > Lo voy a chusmear mas en detalle, pero por lo que veo me viene regio. > > Cualquier cosa vuelvo a molestar con alguna otro consulta. > > Mil gracias. > Saludos > > *Daniel Calvin <[EMAIL PROTECTED]>* escribió: > > Leandro.... me hiciste laburar.... :))) > > Bueno le dedique un rato al problema, no es que el tema me encanta...., y > arme esto. > > El uso seria asi, mira como se vería la clase: > > using System; > using System.Collections.Generic; > using System.Text; > using AlgoDeAtributos00; > namespace AlgoDeAtributos > { > public class AlgunaClase > { > private string[] propiedad; > private string[] otraPropiedad; > > [LazyAttribute(typeof(ProviderA) )] > public string[] Propiedad > { > get { > > propiedad=(string[])LazyFactoryHelper.InvokeLoad(propiedad); > return propiedad; > } > set { propiedad = value; } > } > [LazyAttribute(typeof(ProviderB))] > public string[] OtraPropiedad > { > get > { > otraPropiedad = > (string[])LazyFactoryHelper.InvokeLoad(otraPropiedad); > return otraPropiedad; > } > set { otraPropiedad = value; } > } > public AlgunaClase(){ } > } > } > Antes de avanzar una aclaración, ahora el Lazy funciona como Lazy!!!!!!!!! > Si la propiedad es null se carga, si es distinta de null se respeta el > valor y no se toca.!!!!! > > Veamos el Helper: :))) > > using System; > using System.Collections.Generic; > using System.Text; > using System.Diagnostics; > using System.Reflection; > namespace AlgoDeAtributos00 > { > public static class LazyFactoryHelper > { > public static object InvokeLoad(object destination) > { > if (destination == null) *// Aca se determina si hay que hacer > la carga o no!!!!!!!* > { > StackTrace st = new StackTrace(false); > MethodBase mb = st.GetFrame(1).GetMethod(); > if (mb.IsSpecialName) *// Esto sirve para determinar si el > llamador es una propiedad o un metodo !!!! > * if ( mb.Name.IndexOf("get_", 1, 1, > StringComparison.OrdinalIgnoreCase)!=0)* // Verifica que sea el get de la > propiedad !!!!* > { > PropertyInfo pi = mb.DeclaringType.GetProperty( > mb.Name.Substring(4));* // Obtiene el PropertyInfo del invacador !!!!* > foreach (LazyAttribute o in > pi.GetCustomAttributes(typeof(LazyAttribute), false)) > { > *destination = (o.GetProvider() as > Provider).GetItems(2); // Aqui se invoca la carga desde el provider > obtenido por la factory!!!!! > * } > } > } > return destination; > } > } > } > Bue, te adjunto el ejemplo completo. > > Espero te guste y se ajuste a tu necesidad. Los tipos retornados dependen > de lo que vos declares en tus providers, yo use string[] pero hubiera podido > usar cualquier cosa. > > La contra de este método, va son dos como minimos, 1 *acoplamiento*, 2 Se > explora el stacktrace y no es lo mas performante.... > Lo bueno de este metodo, :) , es *desacoplado*. ( en definitiva estamos > haciendo una forma de IoC ) > > La magia de Net.... > > Saludos > > Daniel Calvin > PD: Contame si te gusto..... > > > El día 16/11/07, Daniel Calvin <[EMAIL PROTECTED]> escribió: > > > > Hola Lenadro > > > > Ese codigo se puede evitar. > > Hay que construir un helper que lo implemente. > > > > Si lo haces con un helper dentro de la propiedad deberías incluir la > > linea que invoque al helper. > > Menos de eso no se puede. > > Si queres hacerlo en forma transparente, sin meter codigo dentro de la > > propiedad, hay que hacer un poco mas de magia. > > En ese caso la entidad la deberias instanciar desde una factory, ese > > factory te retornaría una instancia de un proxy generado al vuelo para esa > > entidad, el se encargaria de implementar el lazy en base al atributo. > > > > Si tengo un rato te escribo el código del helper con un lazy load real, > > eso que escribi no es lazy load, fue solo una muestra de como invocar una > > factory en base a un attibute. > > > > Te estoy mareando?..... > > > > Bue trato de hacerte un ejemplito mas serio. > > > > Saludos > > > > Daniel Calvin > > > > El día 16/11/07, Leandro Tuttini < [EMAIL PROTECTED]> > > escribió: > > > > > > > > > Daniel, la verdad te pasaste muy buen codigo. > > > > > > Se que puede llegar a ser muy complejo, pero como evitaria ingresar > > > este codigo: > > > > > > System.Reflection.PropertyInfo pi =this.GetType > > > ().GetProperty("Propiedad"); > > > foreach (LazyAtribute o in > > > pi.GetCustomAttributes(typeof(LazyAtribute), > > > false)) > > > { > > > propiedad=( o.GetProvider() as > > > Provider).GetItems(2); > > > } > > > > > > en la entidad, y colocarlo dentro del atributo. > > > O es justo esta parte la que mencionabas realizarla con dinamic proxy. > > > > > > > > > Como decia la intriga que tengo es como acceder a propiedad (o su > > > variable privada) de la entidad desde dentro del atributo. > > > Si es que esto se puede. > > > > > > Pero esta muy bueno el codigo, esta bueno como define que provider > > > utilizar. > > > > > > Gracias > > > > > > > > > *Daniel Calvin < [EMAIL PROTECTED]>* escribió: > > > > > > Hola Leandro > > > > > > No es muy lindo lo que vas a hacer, pero te doy una punta. > > > Podes usar StackTrace para que el nombre de la propiedad que invoca al > > > atributo sea dinamica, incluso podrias extraer parte del codigo y meterlo > > > en > > > un helper. > > > > > > El secreto esta en este pedacito: > > > System.Reflection.PropertyInfo pi =this.GetType > > > ().GetProperty("Propiedad"); > > > foreach (LazyAtribute o in > > > pi.GetCustomAttributes(typeof(LazyAtribute), > > > false)) > > > { > > > propiedad=(o.GetProvider() as > > > Provider).GetItems(2); > > > } > > > Es bastante mejorable si te pones. > > > > > > Tenes que tener en cuenta que es muy acoplado, pero, funciona. :)) > > > > > > Te adjunto un rar con la solucion completa, no se si no la filtrara el > > > mug. > > > Por las dudas te pego todo el código aca abajo. > > > > > > Saludos > > > > > > Daniel Calvin > > > PD: Yo usaria proxies dinámicos.... :)) > > > > > > > > > Tu clase sera algo asi si mal no entendi: > > > using System; > > > using System.Collections.Generic; > > > using System.Text; > > > using AlgoDeAtributos00; > > > namespace AlgoDeAtributos > > > { > > > public class AlgunaClase > > > { > > > private string[] propiedad; > > > > > > [LazyAtribute(typeof(ProviderA))] > > > public string[] Propiedad > > > { > > > get { > > > System.Reflection.PropertyInfo pi =this.GetType > > > ().GetProperty("Propiedad"); > > > foreach (LazyAtribute o in > > > pi.GetCustomAttributes(typeof(LazyAtribute), > > > false)) > > > { > > > propiedad=(o.GetProvider() as > > > Provider).GetItems(2); > > > } > > > return propiedad; > > > } > > > set { propiedad = value; } > > > } > > > [LazyAtribute(typeof(ProviderB))] > > > public string[] OtraPropiedad > > > { > > > get > > > { > > > System.Reflection.PropertyInfo pi = > > > this.GetType().GetProperty("OtraPropiedad"); > > > > > > foreach (LazyAtribute o in > > > pi.GetCustomAttributes(typeof(LazyAtribute), > > > false)) > > > { > > > propiedad = (o.GetProvider() as > > > Provider).GetItems(2); > > > } > > > return propiedad; > > > } > > > set { propiedad = value; } > > > } > > > public AlgunaClase(){ } > > > } > > > } > > > > > > > > > Bueno el programita de prueba seria algo asi: > > > using System; > > > using System.Collections.Generic; > > > using System.Text; > > > namespace AlgoDeAtributos > > > { > > > class Program > > > { > > > static void Main(string[] args) > > > { > > > AlgunaClase ac = new AlgunaClase(); > > > foreach (string s in ac.Propiedad ) > > > Console.WriteLine(s); > > > foreach (string s in ac.OtraPropiedad) > > > Console.WriteLine(s); > > > } > > > } > > > } > > > La salida producida algo parecido a esto: > > > Item uno > > > Item dos > > > Item unoPrima > > > Item dosPrima > > > > > > Tu atributo LazyAttributte es algo asi: > > > using System; > > > using System.Collections.Generic; > > > using System.Text; > > > namespace AlgoDeAtributos00 > > > { > > > public class LazyAtribute:Attribute > > > { > > > private Provider provider =null; > > > public LazyAtribute(Type factoryType) > > > { > > > this.provider = factoryType.InvokeMember("", > > > System.Reflection.BindingFlags.CreateInstance, null, this.provider, > > > null) as Provider; > > > } > > > public Provider GetProvider() { return provider; } > > > } > > > } > > > Tus providers para que el ejemplo funcione serian: > > > > > > using System; > > > using System.Collections.Generic; > > > using System.Text; > > > namespace AlgoDeAtributos00 > > > { > > > public abstract class Provider > > > { > > > public abstract string[] GetItems(int family); > > > > > > } > > > public class ProviderA:Provider > > > { > > > public ProviderA() { } > > > public override string[] GetItems(int family) { return new > > > string[] { "Item uno", "Item dos" }; } > > > } > > > public class ProviderB : Provider > > > { > > > public ProviderB() { } > > > public override string[] GetItems(int family) { return new > > > string[] { "Item unoPrima", "Item dosPrima" }; } > > > } > > > } > > > > > > > > > > > > El día 15/11/07, Leandro Tuttini <[EMAIL PROTECTED] > > > > escribió: > > > > > > > > Muchas gracias a todos por las respuestas. > > > > > > > > Les comento, la idea es hacer en un principio algo simple, la > > > > entidad deberia poder utilizar los atributos y a este indicarle que > > > > Factory > > > > de provider utilizar o es el especializado para cargar la propiedad. > > > > Se que con esto queda medio acoplada la entidad pero seria la primer > > > > version de prueba. > > > > > > > > En el final de seguro sera algo con dinamic proxy o algo asi, de > > > > seguro al estilo que se utiliza en Castle project, > > > > http://www.castleproject.org/dynamicproxy/index.html > > > > > > > > Si tienen ejemplos seran de mucha ayuda, que muestre como un > > > > atributo se ejecute antes de la propiedad y que permita setear el valor > > > > de > > > > esta. > > > > Cualquier ejemplo que vean pueden aportar sera de ayuda, y que por > > > > supuesto puedan compartir. > > > > Lo que no me termina de cerrar es como desde un atributo poder > > > > acceder a la variable de la propiedad, para asignarle un valor. > > > > > > > > Diego muy bueno el ejemplo de codeproject, aunque por lo que vi > > > > utiliza una libreria PostSharp, creo que el secreto esta en esta. > > > > > > > > Bueno voy a seguir analizando el tema. > > > > Saludos > > > > ** > > > > ------------------------------ > > > > > > > > Los referentes más importantes en compra/venta de autos se juntaron: > > > > Demotores y Yahoo!. Ahora comprar o vender tu auto es más fácil. > > > > Visitá http://ar.autos.yahoo.com/ > > > > > > > > > > > > > > > > -- > > > Daniel A. Calvin > > > Cooperator Team Member > > > http://www.cooperator.com.ar > > > Microsoft Certified Professional > > > > > > > > > ------------------------------ > > > > > > Los referentes más importantes en compra/venta de autos se juntaron: > > > Demotores y Yahoo!. Ahora comprar o vender tu auto es más fácil. > > > Visitá http://ar.autos.yahoo.com/ > > > > > > > > > > > -- > > Daniel A. Calvin > > Cooperator Team Member > > http://www.cooperator.com.ar > > Microsoft Certified Professional > > > > > > -- > Daniel A. Calvin > Cooperator Team Member > http://www.cooperator.com.ar > Microsoft Certified Professional > > > ------------------------------ > > Los referentes más importantes en compra/venta de autos se juntaron: > Demotores y Yahoo!. Ahora comprar o vender tu auto es más fácil. > Visitá http://ar.autos.yahoo.com/ > > -- Daniel A. Calvin Cooperator Team Member http://www.cooperator.com.ar Microsoft Certified Professional