[patrones] Lazy Load para cargar propiedades

2007-11-19 Por tema Daniel Calvin
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");
> > > foreac

[patrones] Lazy Load para cargar propiedades

2007-11-19 Por tema Leandro Tuttini

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 entida

[patrones] Lazy Load para cargar propiedades

2007-11-16 Por tema Daniel Calvin
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]>* es

[patrones] Lazy Load para cargar propiedades

2007-11-16 Por tema Daniel Calvin
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.

[patrones] Lazy Load para cargar propiedades

2007-11-16 Por tema Leandro Tuttini

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 provide

[patrones] Lazy Load para cargar propiedades

2007-11-15 Por tema Daniel Calvin
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.

[patrones] Lazy Load para cargar propiedades

2007-11-15 Por tema Diego Jancic
Hola Leandro,
PostSharp es open source, asi que se puede ahi tambien :)

Salu2!

On Nov 15, 2007 10:38 AM, Leandro Tuttini <[EMAIL PROTECTED]>
wrote:

> 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/
>
>


[patrones] Lazy Load para cargar propiedades

2007-11-15 Por tema Leandro Tuttini
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/

[patrones] Lazy Load para cargar propiedades

2007-11-14 Por tema Pedro Wood
Hola Leandro, el libro de Patterns of Enterprise Application 
Architecture de Fowler te tira 4 opciones para hacer Lazy Load: Lazy 
Initialization, Virtual Proxy, Value Holder y Ghosts.   
http://martinfowler.com/eaaCatalog/lazyLoad.html
Para colecciones Virtual Proxy me parece de lejos la opción más 
elegante, porque el objeto del dominio ni se entera de que se está 
cargando la colección por lazy load.


No se si era esto lo que buscabas o no, pero si querés te paso el 
ejemplo del libro o alguna implementación mía.


Saludos,

Pedro




Leandro Tuttini escribió:

Hola que tal.

De seguro me meta en un lio con esta pregunta, pero queria realizarla 
igualmente a ver que ideas surgen.


La idea es poder implementar un lazy load casero, o sea no importa si 
se utiliza algun framework o no.


La idea es poder por ejemplo tener una clase Entidad, ejemplo de 
"Region" y poder obtener sus "Instituciones" de esa zona, pudiendo 
cargarse esto en el momento que se invoca.


Por supeusto este Lazy no necesariamente cargara desde un Provider a 
la Base de Datos, podra leer tambien desde un xml, esto igual es 
anecdotico, ya que lo resuelve el provider que se implemente, o mejor 
el factory del provider.


Lo que no llego a terminar de cerrar es como se puede lanzar a la 
ejecucion un atributo en una propiedad de una clase, y que este 
atributo cargue la lista en la variable manejada por la entidad.


Se puede lograr esto? es muy complejo?

public class RegionEntity
{

private List _instituciones;

[Lazy(InstitucionesFactory)]
public List Instituciones
{
get{return _instituciones;}
set{_instituciones = value;}
}

}

Como veran en el ejemplo simple la idea seria lograr que al invocar la 
propiedad, primeramente se llame al atributo y cargue la lista.


Bueno cualquier ayuda ser bienvenida.
Saludos



Compartí video en la ventana de tus mensajes y también tus fotos de 
Flickr.

Usá el Nuevo Yahoo! Messenger versión Beta.
Visitá http://ar.beta.messenger.yahoo.com/ 




[patrones] Lazy Load para cargar propiedades

2007-11-14 Por tema Daniel Calvin
Hola Leandro

Lo que queres hacer se puede hacer, no se si será demasiado práctico, pero
se puede.
Por reflection podes averiguar, ya dentro de la propiedad, del get
concretamente, si esta adornado por algún atributo, la invocación vas a
tener que hacerla vos

En algún lugar debo tener algo de código que usaba algo parecido, no para
lazy, en mi caso era para manejar transacciones

La única ventaja que veo de tu idea es utilizando algún proxy dinámico como
complemento, interceptores o algo pr el estilo, de esa forma podrías
resolver la cuestión en forma transparente.

Esa es tu idea?

Contame.

Daniel Calvin



El día 14/11/07, Leandro Tuttini <[EMAIL PROTECTED]> escribió:
>
> Hola que tal.
>
> De seguro me meta en un lio con esta pregunta, pero queria realizarla
> igualmente a ver que ideas surgen.
>
> La idea es poder implementar un lazy load casero, o sea no importa si se
> utiliza algun framework o no.
>
> La idea es poder por ejemplo tener una clase Entidad, ejemplo de "Region"
> y poder obtener sus "Instituciones" de esa zona, pudiendo cargarse esto en
> el momento que se invoca.
>
> Por supeusto este Lazy no necesariamente cargara desde un Provider a la
> Base de Datos, podra leer tambien desde un xml, esto igual es anecdotico, ya
> que lo resuelve el provider que se implemente, o mejor el factory del
> provider.
>
> Lo que no llego a terminar de cerrar es como se puede lanzar a la
> ejecucion un atributo en una propiedad de una clase, y que este atributo
> cargue la lista en la variable manejada por la entidad.
>
> Se puede lograr esto? es muy complejo?
>
> public class RegionEntity
> {
>
> private List _instituciones;
>
> [Lazy(InstitucionesFactory)]
> public List Instituciones
> {
> get{return _instituciones;}
> set{_instituciones = value;}
> }
>
> }
>
> Como veran en el ejemplo simple la idea seria lograr que al invocar la
> propiedad, primeramente se llame al atributo y cargue la lista.
>
> Bueno cualquier ayuda ser bienvenida.
> Saludos
>
> --
>
> Compartí video en la ventana de tus mensajes y también tus fotos de
> Flickr.
> Usá el Nuevo Yahoo! Messenger versión Beta.
> Visitá http://ar.beta.messenger.yahoo.com/
>
>


-- 
Daniel A. Calvin
Cooperator Team Member
http://www.cooperator.com.ar
Microsoft Certified Professional


[patrones] Lazy Load para cargar propiedades

2007-11-14 Por tema Diego Jancic
Hola Leandro!,

 

Imagino que cuando decis eso estas pensando en ActiveRecord, y pore so
propones la solución con atributos…

Pero lo que hace NH es crear un proxy de la clase, en donde se pone la
lógica del lazy load. Dicho de una forma mas clara, el atributo en ese caso
funciona como un comentario que es visible por el código...

La otra cosa que podes hacer es algo como esto:

 

http://www.codeproject.com/useritems/ps-custom-attributes-1.asp

 

que sinceramente no logre descubrir bien como funciona, pero básicamente lo
que hace es agregar código en tiempo de compilación…

 

Fijate si te sirve.

Saludos,

Diego

 

 

From: [email protected] [mailto:[EMAIL PROTECTED] On Behalf Of Leandro
Tuttini
Sent: Miércoles, 14 de Noviembre de 2007 05:42 p.m.
To: patrones List Member
Subject: [patrones] Lazy Load para cargar propiedades

 

Hola que tal.

De seguro me meta en un lio con esta pregunta, pero queria realizarla
igualmente a ver que ideas surgen.

La idea es poder implementar un lazy load casero, o sea no importa si se
utiliza algun framework o no.

La idea es poder por ejemplo tener una clase Entidad, ejemplo de "Region" y
poder obtener sus "Instituciones" de esa zona, pudiendo cargarse esto en el
momento que se invoca.

Por supeusto este Lazy no necesariamente cargara desde un Provider a la Base
de Datos, podra leer tambien desde un xml, esto igual es anecdotico, ya que
lo resuelve el provider que se implemente, o mejor el factory del provider.

Lo que no llego a terminar de cerrar es como se puede lanzar a la ejecucion
un atributo en una propiedad de una clase, y que este atributo cargue la
lista en la variable manejada por la entidad.

Se puede lograr esto? es muy complejo?

public class RegionEntity
{

private List _instituciones;

[Lazy(InstitucionesFactory)]
public List Instituciones
{
get{return _instituciones;}
set{_instituciones = value;}
}

}

Como veran en el ejemplo simple la idea seria lograr que al invocar la
propiedad, primeramente se llame al atributo y cargue la lista.

Bueno cualquier ayuda ser bienvenida.
Saludos

  

  _  


Compartí video en la ventana de tus mensajes y también tus fotos de Flickr.
Usá el Nuevo Yahoo! Messenger versión Beta. 
Visitá http://ar.beta.messenger.yahoo.com/



[patrones] Lazy Load para cargar propiedades

2007-11-14 Por tema Leandro Tuttini
Hola que tal.

De seguro me meta en un lio con esta pregunta, pero queria realizarla 
igualmente a ver que ideas surgen.

La idea es poder implementar un lazy load casero, o sea no importa si se 
utiliza algun framework o no.

La idea es poder por ejemplo tener una clase Entidad, ejemplo de "Region" y 
poder obtener sus "Instituciones" de esa zona, pudiendo cargarse esto en el 
momento que se invoca.

Por supeusto este Lazy no necesariamente cargara desde un Provider a la Base de 
Datos, podra leer tambien desde un xml, esto igual es anecdotico, ya que lo 
resuelve el provider que se implemente, o mejor el factory del provider.

Lo que no llego a terminar de cerrar es como se puede lanzar a la ejecucion un 
atributo en una propiedad de una clase, y que este atributo cargue la lista en 
la variable manejada por la entidad.

Se puede lograr esto? es muy complejo?

public class RegionEntity
{

private List _instituciones;

[Lazy(InstitucionesFactory)]
public List Instituciones
{
get{return _instituciones;}
set{_instituciones = value;}
}

}

Como veran en el ejemplo simple la idea seria lograr que al invocar la 
propiedad, primeramente se llame al atributo y cargue la lista.

Bueno cualquier ayuda ser bienvenida.
Saludos

   
-

Compartí video en la ventana de tus mensajes y también tus fotos de Flickr.
Usáel Nuevo Yahoo! Messenger versión Beta. 
 Visitá http://ar.beta.messenger.yahoo.com/