Declarar una clase de manera dinámica en WebForms

19/07/2005 - 11:56 por Jordi Julià | Informe spam
Hola a todos,

Necesitaria saber como puedo declarar una clase de manaera dinámica, en Web
Forms. Me explico

En un proyecto tengo una clase llamada Mantenimiento:

Class Mantenimiento
...
End class


Si quiero acceder a una función dentro de la clase, hago lo siguiente:

dim mn as new Mantenimiento
mn.FuncionAEjecutar()

Lo que quiero hacer es lo siguiente

dim mn as new "Nombre de la clase"
mn.FuncionAEjecutar()

¿como se puede hacer, declarar una clase de manera dinámica en WebForms?

Saludos
Jordi

Preguntas similare

Leer las respuestas

#1 Eduardo A. Morcillo [MS MVP VB]
19/07/2005 - 16:14 | Informe spam
Puedes utilizar la clase System.Activator para crear la instancia pero vas a
necesitar declarar la variable con algun tipo que no sea Object para poder
utilizarla. Pueder crear una interface con los metodos que quieres llamar de
estas clases e implementar la interface en las clases. Al momento de
llamarla utilizas la interface para declara la variable. Por ejemplo:

Interface MiInterface

Sub MiMetodo()

End Interface

Class MiClase
Implements MiInterface

Sub MiMetodo Implements MiInterface.MiMetodo
' Codigo
End Sub

End Class

Dim t As Type = Type.GetType("MiClase")
Dim mn As MiInterface = DirectCast(Activator.CreateInstance(t), MiInterface)

mn.MiMetodo()

Eduardo A. Morcillo [MS MVP VB]
http://www.mvps.org/emorcillo
Respuesta Responder a este mensaje
#2 Jordi Julià
20/07/2005 - 12:32 | Informe spam
Gracias Eduardo por la respuesta,

Lo que me sorprende es lo que comentas del tipo Object de la Clase, me
explico, después de poner mi mensaje de "ayuda" segui investigando y
probando y conseguí resultados, te adjunto un extracto:

Dim Clase As Object

Params(0) = Compañia
Params(1) = Idioma
Params(2) = connSQL
Params(3) = connOLEDB

sAssembly = System.Reflection.Assembly.GetExecutingAssembly.FullName
Ass = System.Reflection.Assembly.Load(sAssembly)

Dim arr As Array
arr = Split(sAssembly, ",")
NombreProyecto = arr(0)

sTipo = Ass.GetType(NombreProyecto & Chr(46) & NombreClase)
Clase = Activator.CreateInstance(sTipo, Params)



Dim Tipo As Type
Dim ei As System.Reflection.EventInfo
Dim Delegado As [Delegate]

Tipo = Control.GetType
ei = Tipo.GetEvent(NombreEvento)

If Not ei Is Nothing Then
Delegado = [Delegate].CreateDelegate(ei.EventHandlerType, Clase,
SubRutinaEvento, True)
ei.AddEventHandler(Control, Delegado)
End If

La idea es poder asociar eventos de los controles de una página para que
ejecute las funciones pertinentes en una clase determinada que debe existir
en el proyecto, como ves utilizo el "Activator" pero mantengo el objeto de
la clase como Object.
¿estoy haciendo algún disparate?

Saludos
Jordi






"Eduardo A. Morcillo [MS MVP VB]" <emorcillo .AT. mvps.org> escribió en el
mensaje news:
Puedes utilizar la clase System.Activator para crear la instancia pero vas


a
necesitar declarar la variable con algun tipo que no sea Object para poder
utilizarla. Pueder crear una interface con los metodos que quieres llamar


de
estas clases e implementar la interface en las clases. Al momento de
llamarla utilizas la interface para declara la variable. Por ejemplo:

Interface MiInterface

Sub MiMetodo()

End Interface

Class MiClase
Implements MiInterface

Sub MiMetodo Implements MiInterface.MiMetodo
' Codigo
End Sub

End Class

Dim t As Type = Type.GetType("MiClase")
Dim mn As MiInterface = DirectCast(Activator.CreateInstance(t),


MiInterface)

mn.MiMetodo()

Eduardo A. Morcillo [MS MVP VB]
http://www.mvps.org/emorcillo


Respuesta Responder a este mensaje
#3 Eduardo A. Morcillo [MS MVP VB]
20/07/2005 - 16:29 | Informe spam
No estas haciendo ningun disparate. Pero tampoco estas llamando a algun
metodo de la clase directamente (que es a lo que yo hacia referencia) sino
que lo hace el control a traves del delegado.

Otra cosa seria si quisieras ejecutar desde tu codigo algun metodo de la
clase. Si bien puedes hacerlo desde una variable de tipo Object (si esta
seteado Option Strict Off), yo no te recomendaria ese uso ya que de esta
forma no tendrias chequeo de la funcion al momento de compilar y se
resolveria usando Reflection al momento de ejecutarla, lo que lo hace mas
lento y mas propenso a errores.

Eso si, tu codigo tambien podria beneficiarse si haces lo que te decia en el
mensaje anterior porque CreateDelegate tambien usa reflection y no tienes
forma de asegurar hasta es llamada que la clase implementa el metodo que
quieres que maneje el evento del control. Podrias hacerlo asi:

Interface ManejaClick

' La interface deberia definirse en un proyecto diferente y
' referenciarlo en el proyecto principal y el de la DLL.

Sub Click(ByVal sender As Object, ByVal e As EventArgs)

End Interface

Clase ManejaEventos
Implements ManejaClick

Sub Click(ByVal sender As Object, ByVal e As EventArgs) Implements
ManejaClick.Click
' Codigo aqui
End Sub

End Class

Dim clase As ManejaClick

' Aqui deberias chequear excepciones en caso de que no pueda crear la clase
o
' la clase no implemente la interface
clase = DirectCast(Activator.CreateInstance(sTipo, Params), ManejaClick)

AddHandler Control, AddressOf clase.Click

Como puedes ver, es mucho mas simple y sin tanto Reflection, lo que mejora
el rendimiento y evita errores que se dan al ejecutar la aplicacion y son
mas complicados de corregir.

Eduardo A. Morcillo [MS MVP VB]
http://www.mvps.org/emorcillo
Respuesta Responder a este mensaje
#4 Jordi Julià
21/07/2005 - 14:03 | Informe spam
Hola Eduardo,

Al final después de estudiar lo que me has comentado he dejado mi función de
la siguiente manera:

'Establecer parámetros del contructor de la clase
Dim Params(3) as Objet

'Obtener el nombre del proyecto
Dim arr As Array
Dim sAssembly as string System.Reflection.Assembly.GetExecutingAssembly.FullName
arr = Split(sAssembly, ",")
dim NombreProyecto as string = arr(0)

'Crear la instancia de clase de manera dinámica
sTipo = Type.GetType(NombreProyecto & Chr(46) & NombreClase)
Clase = Activator.CreateInstance(sTipo, Params)


No he aplicado el tema de la "Interfase" y los "Implements" porque me
complican en exceso la gestión de eventos que también la gestiono de manera
virtual (la idea que estoy desarrollando es la generación y ejecución de
webs definidas en tablas sql, tengo una tabla de páginas, otra de controles
y otra de eventos). Trabajando la clase se esta manera el proceso me
funciona y los eventos me derivan a las funciones que quiero.

Me podrías aconsejar si la manera en que obtengo el nombre del proyecto es
óptima o si lo obtendrías de alguna otra manera.

Saludos y muchas gracias
Jordi




"Eduardo A. Morcillo [MS MVP VB]" <emorcillo .AT. mvps.org> escribió en el
mensaje news:
No estas haciendo ningun disparate. Pero tampoco estas llamando a algun
metodo de la clase directamente (que es a lo que yo hacia referencia) sino
que lo hace el control a traves del delegado.

Otra cosa seria si quisieras ejecutar desde tu codigo algun metodo de la
clase. Si bien puedes hacerlo desde una variable de tipo Object (si esta
seteado Option Strict Off), yo no te recomendaria ese uso ya que de esta
forma no tendrias chequeo de la funcion al momento de compilar y se
resolveria usando Reflection al momento de ejecutarla, lo que lo hace mas
lento y mas propenso a errores.

Eso si, tu codigo tambien podria beneficiarse si haces lo que te decia en


el
mensaje anterior porque CreateDelegate tambien usa reflection y no tienes
forma de asegurar hasta es llamada que la clase implementa el metodo que
quieres que maneje el evento del control. Podrias hacerlo asi:

Interface ManejaClick

' La interface deberia definirse en un proyecto diferente y
' referenciarlo en el proyecto principal y el de la DLL.

Sub Click(ByVal sender As Object, ByVal e As EventArgs)

End Interface

Clase ManejaEventos
Implements ManejaClick

Sub Click(ByVal sender As Object, ByVal e As EventArgs) Implements
ManejaClick.Click
' Codigo aqui
End Sub

End Class

Dim clase As ManejaClick

' Aqui deberias chequear excepciones en caso de que no pueda crear la


clase
o
' la clase no implemente la interface
clase = DirectCast(Activator.CreateInstance(sTipo, Params), ManejaClick)

AddHandler Control, AddressOf clase.Click

Como puedes ver, es mucho mas simple y sin tanto Reflection, lo que mejora
el rendimiento y evita errores que se dan al ejecutar la aplicacion y son
mas complicados de corregir.

Eduardo A. Morcillo [MS MVP VB]
http://www.mvps.org/emorcillo


Respuesta Responder a este mensaje
#5 Eduardo A. Morcillo [MS MVP VB]
21/07/2005 - 16:35 | Informe spam
Me podrías aconsejar si la manera en que obtengo el nombre del
proyecto es óptima o si lo obtendrías de alguna otra manera.



Usa System.Reflection.Assembly.GetExecutingAssembly.GetName.Name es mas
directo y no tienes que estar haciendo un Split.

Eduardo A. Morcillo [MS MVP VB]
http://www.mvps.org/emorcillo
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida