Con esto cerramos los proxis dinámicos de EF

En mi anterior post y con bastante ánimo de critica intente explicar mi desacuerdo con ciertas cosas que pasan sin nuestro control. En este lo que intento es que todos conozcáis que es lo que pasa con algunas recomendaciones “Si trabajas con EF declara tus propiedades como virtual que es mejor” .

Mejor ¿Por qué?. Vamos a verlo:).

Si pensamos detenidamente cuando yo declaro algo con el modificador de acceso virtual es porque lo dejo preparado para que otra persona sea capaz de reemplazarlo con override. Es así no?.

Para poneros un poco en antecedentes os recomiendo estos dos post que os pueden ayudar a aclarar ciertas dudas.

Seguro que más de uno lo ha leído, pues Codefirst funciona igual y sino de donde la magia.

Pero me quedo con esta frase “Proxies are a form of dependency injection where additional functionality is injected into the entity”. Para mi no es Inyección de dependencias yo creo que mas que eso es una invasión:).

Otra cosa que me dio bastantes pistas fue esto

“The EF generates proxy types on the fly using the AssemblyBuilder and TypeBuilder in the .NET framework. All the code to perform lazy loading and change tracking is added to the dynamically generated types using the Reflection.Emit APIs”

Mi gran amigo Reflection.Emit desconocido pero potente para invadir. Bueno llegados a este punto, es darle un poco a la imaginación y a las malas artes para descubrir quien hace todo eso. Tras dar vueltas al código fuente con Reflector me encuentro con una clase internal. Como no!!!. Señores public y si puede ser  OpenSource que esto hará que EF crezca.

Sabéis el nombre pues os lo digo

Clase :“EntityProxyFactory” 

Namespace:“System.Data.Objects.Internal”

Dll: “System.Data.Entity.dll”.

Si esa que esta instalada en la GAC y que por mucho que con Nuget actualicemos la versión de EF nunca cambia.

Os acordáis de mi anterior post ese modelo malicioso de Facturas y Clientes,  bueno ahora voy a hacer con el otra cosa y es ver que genera EF por nosotros.

Para ello voy a utilizar reflection y acceder a ciertos campos privados de esa clase y modificarlos para poder guardar en disco la dll generada.

   1: BindingFlags Flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

   2: using (ModelFacturas db = new ModelFacturas())

   3: {

   4:    //Obtenemos el ensamblado System.Data.Entity.Dll

   5:    Assembly a = typeof(System.Data.Objects.ObjectContext).Assembly;

   6:    

   7:    //Obtenemos el tipo EntityProxiFactory

   8:    var type = (from item in a.GetTypes()

   9:                where item.Name == "EntityProxyFactory"

  10:                select item).FirstOrDefault();

  11:  

  12:    //Modificamos el campo privado s_ProxyAssemblyBuilderAccess para

  13:    //permitir que el ensamblado dinamico se pueda guardar

  14:    //por defecto AssemblyBuilderAccess está marcado como Run

  15:    //Es decir se puede ejecutar pero no se puede Guardar

  16:    var field = type.GetField("s_ProxyAssemblyBuilderAccess", Flags);

  17:    

  18:    object o = Activator.CreateInstance(type);

  19:    field.SetValue(o, AssemblyBuilderAccess.RunAndSave);

  20:  

  21:    //provocamos que EF genere el proxi dinamico

  22:  

  23:    var cliente = db.Clientes.AsEnumerable().FirstOrDefault();

  24:    var facturas = db.Facturas.AsEnumerable().FirstOrDefault();             

  25:    

  26:    //Accedemos al ensamblado dinamico y lo guardamos en disco

  27:    var field2 = type.GetField("s_ModuleBuilders", Flags);

  28:  

  29:    Dictionary<Assembly, ModuleBuilder> dic = field2.GetValue(o) as Dictionary<Assembly, ModuleBuilder>;

  30:    if (dic.Any())

  31:    {

  32:        AssemblyBuilder asm = dic.First().Value.Assembly as AssemblyBuilder;

  33:        asm.Save("tequieroconocer.dll");

  34:    }   

  35: }

Pues a partir de este momento ya tenemos en nuestro directorio de ejecución.  Una dll llamada “tequieroconocer.dll”. El siguiente paso es sencillo la abrimos con cualquier herramienta como Reflector y a disfrutar y conocer:).

Dibujo

 

Fijaos en la magia, nuestras clases originales han sido alteradas e implementan dos interfaces

El resto de cosas os las dejo para que investiguéis, vosotros y de esa forma conocer a fondo este Framework, que tiene sus cosas buenas y otras que no son tan buenas.

Conclusiones.

El conocimiento no debe de tener limites , por lo tanto tiene que ser público y es por esto el motivo de este post.

Sobre todo os tenéis que acordar de dos parámetros importantes cuando utilicéis EF.

Ya conocéis un poquito más de ellos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *