Un poquito System.Activator

Bueno, una vez cuando comencé a trabajar ya como ingeniero de sistemas en un entorno real, conocí algo que yo decía que tenia que existir, y era formar un menú desde la base de datos, dependiendo del usuario; pues hasta aquí todo bien, pues la forma mas lógica para mi en ese momento era agregar todas las opciones del menú a mi forma principal, y después ir preguntando si en realidad el usuario estaba habilitado a entrar a este ítem.



Después cuando conocí un poco de seguridad, supe que esta forma era incorrecta, por que hacerlo de esa manera, le incitaba al usuario a que “tratara de dañar” el aplicativo de alguna forma para entrar a las opciones que el podía ver que existían pero no eran para su uso; para resolver este problema, agregaba todas las opciones al menú, después cuando iniciaba la aplicación, verificaba las opciones que el usuario tenia disponibles y las que no las eliminaba del menú.



Obtuve en cierta parte el resultado de lo que necesitaba, pero aun era una mala solución, puesto que si mi aplicación crecía, tenía que modificar todo el menú, o por lo menos agregar las nuevas opciones. Entonces descubrí que tampoco era lógico, viable y mucho menos extensible.



Como decía, cuando comencé a trabajar en serio a modo productivo, mi eterno maestro, me dio una luz, y era cargar el menú en tiempo de ejecución, agregar los botones o las opciones disponibles, leyendo desde la base de datos. Si listo, hasta ahí de maravillas, pero…. Yo en una base de datos no puedo guardar objetos totalmente entendibles para mi lenguaje de programación, en este caso C#, cuando mas en una base de datos puedo tener el nombre del formulario, la ubicación del formulario, la fecha de creación, el usuario que lo creo, y es mas si quiero ( y la base de datos me lo permite) puedo hasta guardar las clases (el archivo físico) en la base de datos, la dll que los contiene, en fin lo que sea, pero nunca podría decirle que abriera el formulario. Bueno, una persona de la cual sigo aprendiendo, con la que trabajo, tiene una implementación, solucionando mi problema, pero escrita en vb….6 :(.



Solo recitaba, el nombre del formulario, y el nombre de la dll que contiene al formulario, la implementación de esta maravilla (para mi) en C#, la proporciona la clase System.Activator, “esta clase nos facilita crear tipos de objetos de forma local o remota, o para obtener referencias a objetos remotos existentes”, bueno esa fue la traducción que obtuve de Google; a palabras sencillas, es una clase que me permite crear Tipos de objetos y una vez tengo el Tipo, pues…puedo crear el objeto. Mejor lo explico con un ejemplo.



Entramos a Visual Studio, creamos un proyecto Windows Form, yo lo llame, Llamame. Nos olvidamos del form, y agregamos una clase, que llame Llamador.cs, es una clase publica y estatica, en donde vamos a colocar los metodos necesarios para poder crear la instancia de un objeto con solo saber el nombre del objeto y el nombre del ensamblado.



Como lo que queremos es llamar un formulario a partir de su nombre, entonces escribiremos un método que me regrese un verdadero o falso, dependiendo si el string que le pasamos como parámetro corresponde en realidad a un formulario. Lo llamaremos IsFormulario, nos devolverá un Verdadero si el objeto resultante del string es un Formulario, en caso contrario un Falso.



El nombre de la dll, el campo NombreDll, lo podemos dejar null, y la clase la buscara por si sola. Esto lo podemos mejorar, y agilizar nuestra programación si en ves de devolvernos un bool nos regresa el formulario.



En la misma clase agregamos un metodo que nos abra el formulario.



Con este método comprobaremos que es un formulario y además lo muestra, si somos un poco más imaginativos, podemos unir cosas del post anterior, así que podemos abrir nuestro nuevo formulario y agregarlo a nuestro formulario Principal. Eso es tema para otro post.



Bueno ahora veamos un video aplicando todo esto.






Bueno ahora vamos a ver una introducción a lo que me refería primero, tener un menú personalizado según un usuario, voy a utilizar dos usuarios, uno Administrador y un usuario Normal.



O sea, que tenemos que agregar unos formularios mas a nuestro proyecto, los de los colores, con sus respectivos nombres, en ellos agregamos lo que queramos. Para obtener el efecto de leer el menu de la base de datos voy a crear dos colecciones de string, cada una con los nombres de los formularios que puede abrir cada menu.






Bueno ahora, hay que buscar la forma de convertir esos string en botones.



A este método le pasaremos la lista de string que corresponda, y en nuestro FlowLayoutPanel agregara los botones. Utilizamos el Replace para quitar el nombre del namespace y dejar solo el nombre del formulario. Además agregamos el nombre completo del formulario al Tag del botón, y poder ubicarlo fácilmente. Aun falta agregarle el evento que mostrara el formulario.







Por ultimo falta agregar algo para que nos deje elegir cual menú queremos, si el de administrador o el Normal. Además en el método ConvertirEnBoton tenemos que agregarle un pequeño código para que limpie los botones.



Finalmente.



Espero les haya gustado, con un poco mas de imaginación se pueden hacer muchas cosas, utilize una lista para guardar los nombres de los formularios, pero la idea es leerlos de una base de datos.

Comentarios

  1. Pos como que cual DLL. estas cargando un ActiveX de Visual Basic 6.0 (bueno, creo que estas librerias de visual basic 6 se crean con extencion OCX) ahora cuando haces esto:


    System.Runtime.Remoting.ObjectHandle objh = Activator.CreateInstance(NombreDLL,NombreFormulario)

    Estas cargando un Ensamblado...

    CreateInstance(String, String) --->

    Crea una instancia del tipo cuyo nombre se especifica, utilizando el ensamblado con nombre y el constructor predeterminado.

    cual es el ensamblado que llamas...de donde lo sacas..

    ResponderEliminar
  2. Interesante, ademas que un tema muy útil y como tu mismo lo mencionas con un poco de imaginacion se pueden hacer cosas muy bien construidas.
    Por otro lado creo que tu manera de presentarlo no fue la mejor.
    Te sugiero que para próximas entradas hagas primero un mapa conceptual de que es lo que quieres mostrar y tengas claramente definido el libreto pues realmente lo tuve que leer varias veces para darme cuenta a donde conducian los diferentes 'retazos' que has colocado. Creo que esta muy desordenado el hilo y eso hace que uno se confunda.

    ResponderEliminar
  3. Gracias Juan Carlos por la sugerencia la tendre en cuenta

    ResponderEliminar
  4. Para Visual C
    si tu dejas el campo del nombre del ensamblado en null, Activator busca automaticamente el objeto dentro de las clases del ensamblado que lo llama. osea el local, si yo quisiera llamar a otra dll, en nombre del ensamblado pongo el nombre de la dll. en la MSDN dice

    Nombre del ensamblado donde se busca el tipo denominado typeName. Si assemblyName es referencia null (Nothing en Visual Basic), se busca el ensamblado que se está ejecutando.

    Aun sigo buscando sobre lo que me dices del OCX, pero no encuentro nada que me referencie eso con visual basic, depronto estas confundiéndote, yo no estoy utilizando nada de visual basic 6, yo digo, que vi un ejemplo en visual basic que hace algo parecido a lo que estoy haciendo yo en este post. No te puedo decir mucho de visual basic, por que aunque trabajo con VB6 no me gusta mucho, voy a tratar de conseguir el ejemplo.

    De todas formas, voy a subir el proyecto, para que te des cuenta que no hago ninguna referencia a nada de VB6.

    ResponderEliminar
  5. Que hay man.... ahora que estuve leyendo su articulo... falto codigo fuente para complementar lo que no se ve en el video... ;)


    SuerteX :)

    ResponderEliminar

Publicar un comentario