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

Responder a