Acceso a los tipos de un ensamblado

11/05/2004 - 19:04 por josecarloyplancharlo | Informe spam
Mi gran problema es el siguiente:

Tengo un proyecto que llama a un DLL llamado Repositorio, el cual
recibe el tipo de una interfaz y tras buscar en un XML, obtiene la
clase que implementa dicha interfaz: algo así

// Proyecto en C#

void main(..){
...
Interfaz i = (Interfaz)(Repositorio.CrearImplementacion(typeof(Interfaz)));
...
}

// fin proyecto en C#

-

// DLL Repositorio

static object CrearImplementacion( Type Itype ){
... // busqueda en el XML

Assembly componente = Assembly.LoadFrom( DireccionDLL );
object obj = component.CreateInstance( Itype.Name );
return obj;

}

// Fin DLL

-

Es decir, una aplicación normal ( con la definición de la interfaz )
llama a un método estático de un DLL ( cargado previamente con Agregar
Referencia ) con un tipo que conoce ( Interfaz ).

El problema es que Repositorio que es un DLL llama a otro DLL y en la
depuración del proyecto observo que obj si contiene la clase que
implementa la Interfaz, pero surge una excepción del tipo "No se puede
convertir explicitamente", es decir, no puede hallar la definición de
la clase que implementa la interfaz.

Una solución que si conseguí es que en el proyecto la Interfaz i sea
object i, de tal forma que para acceder a los métodos del objeto
tendría que utilizar InvokeMember(), pero mi intención no es esa. Un
ejemplo:

// Proyecto C#

interface IPersona{
void SetNombre( string );
void SetEdad( int );
}

void main(){
IPersona p = (IPersona)Repositorio.CrearImplementacion(typeof(IPerson));
p.SetNombre( "Juan" );
p.SetEdad( 25 );
}

// Fin proyecto C#

mi intención es la siguiente:

1.- Repositorio.CrearImplementacion recibe un tipo, mediante el cual
busca en un XML qué DLL tiene implementado la clase Persona.
2.- Si lo ha encontrado, carga el DLL y crea un objeto de tipo
Persona, puesto que no se pueden crear objetos de una interfaz.
3.- Dicho objeto de la clase Persona se devuelve al proyecto y se
pueden ejecutar los métodos de la interfaz, puesto que tengo en el
objeto devuelto por el repositorio una implementación para dicha
interfaz.


Pero no puedo hacer la conversión.
Cualquier sugerencia tanto que funcione como que no será muy
agradecida. Gracias !!!

Preguntas similare

Leer las respuestas

#6 josecarloyplancharlo
12/05/2004 - 19:23 | Informe spam
La solución que ofreció Octavio me funciona siempre que tenga dos
ficheros:

// Repositorio.dll
using System;

namespace NSPRepositorio
{
/// <summary>
/// Descripción breve de Class1.
/// </summary>
public class Repositorio
{
public static object CrearImplementacion(Type Itype)
{
object obj = new Persona();
return obj;
}
}


public interface IPersona
{
void Imprimir();
}

public class Persona : IPersona
{
public Persona(){}

public void Imprimir()
{
Console.WriteLine("pepe");
}
}
}
// Fin Repositorio.dll

// Proyecto de Ejemplo
using System;
using NSPRepositorio;

namespace Ej
{
/// <summary>
/// Descripción breve de Class1.
/// </summary>
class Class1
{
/// <summary>
/// Punto de entrada principal de la aplicación.
/// </summary>
[STAThread]
static void Main(string[] args)
{
object obj1 = (IPersona)(Repositorio.CrearImplementacion(typeof(IPersona)));
IPersona i = (IPersona)(Repositorio.CrearImplementacion(typeof(IPersona)));
i.Imprimir();
}
}
}
// Fin Proyecto de Ejemplo


En este ejemplo, obj1 e i es de tipo NSPRepositorio.Persona ( obvio
proque se ha agregado como referencia en tiempo de compilación el
NSPRepositorio de Repositorio.dll ).

Pero no es exactamente mi problema y creo que vá mas encaminado
Tristan por el hecho de que para que todo funcione:

- el proyecto posee la definición de la interfaz por NSPRepositorio
- el repositorio debe cargar dinámicamente el ensamblado
"C:\\Repositorio\\DLLPersona\\Persona.dll" y crear un objecto de dicho
tipo ( con Assembly, CreateIntance o InvokeMember ... )
- el repositorio tras cargar el Assembly y obtener el objeto
(supuestamente) NSPPersona.Persona devuelve dicho objeto al proyecto,
el cual lo debe usar como siempre.

No sé si no he cargado bien el ensamblado o que me hace falta algo,
pero creo que tiene algo que ver conque los tipos son iguales pero en
diferentes NameSpaceŽs.

Cuanto antes os llevo todo el código para que le hechéis un vistazo.
Gracias !!!
Respuesta Responder a este mensaje
#7 Alvaro Mateos [MS]
13/05/2004 - 01:33 | Informe spam
El problema está en que al la hora de instanciar una clase por reflection
debemos especificar el nombre de una clase, y no una interfaz. Parece lógico
pues un assembly puede contener más de una clase que implemente un interfaz
y en tal caso no se sabría cual debería instanciar.

Para que funciones se debe especificar el nombre completo de la clase
(Namespace.NombreClase) que implementa el interfaz. Por lo tanto el fichero
Xml deberá contener tanto el assembly como el nombre completo de la clase.

Saludos,

Alvaro Mateos [MS]
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no
otorga ningún derecho


"secharles" wrote in message
news:
Mi gran problema es el siguiente:

Tengo un proyecto que llama a un DLL llamado Repositorio, el cual
recibe el tipo de una interfaz y tras buscar en un XML, obtiene la
clase que implementa dicha interfaz: algo así

// Proyecto en C#

void main(..){
...
Interfaz i (Interfaz)(Repositorio.CrearImplementacion(typeof(Interfaz)));
...
}

// fin proyecto en C#


// DLL Repositorio

static object CrearImplementacion( Type Itype ){
... // busqueda en el XML

Assembly componente = Assembly.LoadFrom( DireccionDLL );
object obj = component.CreateInstance( Itype.Name );
return obj;

}

// Fin DLL


Es decir, una aplicación normal ( con la definición de la interfaz )
llama a un método estático de un DLL ( cargado previamente con Agregar
Referencia ) con un tipo que conoce ( Interfaz ).

El problema es que Repositorio que es un DLL llama a otro DLL y en la
depuración del proyecto observo que obj si contiene la clase que
implementa la Interfaz, pero surge una excepción del tipo "No se puede
convertir explicitamente", es decir, no puede hallar la definición de
la clase que implementa la interfaz.

Una solución que si conseguí es que en el proyecto la Interfaz i sea
object i, de tal forma que para acceder a los métodos del objeto
tendría que utilizar InvokeMember(), pero mi intención no es esa. Un
ejemplo:

// Proyecto C#

interface IPersona{
void SetNombre( string );
void SetEdad( int );
}

void main(){
IPersona p (IPersona)Repositorio.CrearImplementacion(typeof(IPerson));
p.SetNombre( "Juan" );
p.SetEdad( 25 );
}

// Fin proyecto C#

mi intención es la siguiente:

1.- Repositorio.CrearImplementacion recibe un tipo, mediante el cual
busca en un XML qué DLL tiene implementado la clase Persona.
2.- Si lo ha encontrado, carga el DLL y crea un objeto de tipo
Persona, puesto que no se pueden crear objetos de una interfaz.
3.- Dicho objeto de la clase Persona se devuelve al proyecto y se
pueden ejecutar los métodos de la interfaz, puesto que tengo en el
objeto devuelto por el repositorio una implementación para dicha
interfaz.


Pero no puedo hacer la conversión.
Cualquier sugerencia tanto que funcione como que no será muy
agradecida. Gracias !!!
Respuesta Responder a este mensaje
#8 josecarloyplancharlo
13/05/2004 - 14:20 | Informe spam
Si el problema no es el NameSpace, porque el objeto que recibo es del
dipo NombreNameSpace.NombreClase. El problema es que me dice que no
puede convertir
NombreNameSpace1.NombreClase a NombreNameSpace.NombreClase !


"Alvaro Mateos [MS]" wrote in message news:...
El problema está en que al la hora de instanciar una clase por reflection
debemos especificar el nombre de una clase, y no una interfaz. Parece lógico
pues un assembly puede contener más de una clase que implemente un interfaz
y en tal caso no se sabría cual debería instanciar.

Para que funciones se debe especificar el nombre completo de la clase
(Namespace.NombreClase) que implementa el interfaz. Por lo tanto el fichero
Xml deberá contener tanto el assembly como el nombre completo de la clase.

Saludos,

Alvaro Mateos [MS]
Este mensaje se proporciona "como está" sin garantías de ninguna clase, y no
otorga ningún derecho


"secharles" wrote in message
news:
> Mi gran problema es el siguiente:
>
> Tengo un proyecto que llama a un DLL llamado Repositorio, el cual
> recibe el tipo de una interfaz y tras buscar en un XML, obtiene la
> clase que implementa dicha interfaz: algo así
>
> // Proyecto en C#
>
> void main(..){
> ...
> Interfaz i > (Interfaz)(Repositorio.CrearImplementacion(typeof(Interfaz)));
> ...
> }
>
> // fin proyecto en C#
>
>
> // DLL Repositorio
>
> static object CrearImplementacion( Type Itype ){
> ... // busqueda en el XML
>
> Assembly componente = Assembly.LoadFrom( DireccionDLL );
> object obj = component.CreateInstance( Itype.Name );
> return obj;
>
> }
>
> // Fin DLL
>
>
> Es decir, una aplicación normal ( con la definición de la interfaz )
> llama a un método estático de un DLL ( cargado previamente con Agregar
> Referencia ) con un tipo que conoce ( Interfaz ).
>
> El problema es que Repositorio que es un DLL llama a otro DLL y en la
> depuración del proyecto observo que obj si contiene la clase que
> implementa la Interfaz, pero surge una excepción del tipo "No se puede
> convertir explicitamente", es decir, no puede hallar la definición de
> la clase que implementa la interfaz.
>
> Una solución que si conseguí es que en el proyecto la Interfaz i sea
> object i, de tal forma que para acceder a los métodos del objeto
> tendría que utilizar InvokeMember(), pero mi intención no es esa. Un
> ejemplo:
>
> // Proyecto C#
>
> interface IPersona{
> void SetNombre( string );
> void SetEdad( int );
> }
>
> void main(){
> IPersona p > (IPersona)Repositorio.CrearImplementacion(typeof(IPerson));
> p.SetNombre( "Juan" );
> p.SetEdad( 25 );
> }
>
> // Fin proyecto C#
>
> mi intención es la siguiente:
>
> 1.- Repositorio.CrearImplementacion recibe un tipo, mediante el cual
> busca en un XML qué DLL tiene implementado la clase Persona.
> 2.- Si lo ha encontrado, carga el DLL y crea un objeto de tipo
> Persona, puesto que no se pueden crear objetos de una interfaz.
> 3.- Dicho objeto de la clase Persona se devuelve al proyecto y se
> pueden ejecutar los métodos de la interfaz, puesto que tengo en el
> objeto devuelto por el repositorio una implementación para dicha
> interfaz.
>
>
> Pero no puedo hacer la conversión.
> Cualquier sugerencia tanto que funcione como que no será muy
> agradecida. Gracias !!!
Respuesta Responder a este mensaje
#9 Tristan
13/05/2004 - 14:46 | Informe spam
¿Secharles, pero has probado a definir el interface en un ensamblado común?.

Te sigo diciendo que dos clases o interfaces se consideran distintas, aunque
se llamen igual, tengan los mismos métodos, e incluso aunque provengan del
mimso fuente. Ten en cuenta que en .net, la versión del ensamblado forma
parte de la clase, y no podrás hacer casting de una clase que implemente una
interface a una interface que provenga de un ensamblado distinto. ¿Entiendes
lo que te digo?.

Si realmente el interface proviene del mismo ensamblado, me gustaría
saberlo, por que realmente tengo curiosidad por entenderte.

Juan Carlos Badiola
MVP - C#
Respuesta Responder a este mensaje
#10 josecarloyplancharlo
14/05/2004 - 12:16 | Informe spam
Hola Tristan, yo inicialmente tenía la interfaz IPerson en el
ensamblado Persona.dll, pero para poder definirlo en el proyecto de
prueba, tengo que incluirlo también en él.

La solución que tengo ahora mismo es que defino la misma interfaz en
el Repositorio.dll, en otras palabras, el proyecto de ejemplo tiene
una referencia a Repositorio.dll que contiene la definición de la
interfaz IPerson, que también está definido en Persona.dll, entonces
claro, no son la misma definición. Creo que la solución es que
Persona.dll tenga la referencia del Repositorio.dll para que comparta
la definición de la interfaz y así sea el mismo, ¿ que opinas ?



"Tristan" wrote in message news:<#...
¿Secharles, pero has probado a definir el interface en un ensamblado común?.

Te sigo diciendo que dos clases o interfaces se consideran distintas, aunque
se llamen igual, tengan los mismos métodos, e incluso aunque provengan del
mimso fuente. Ten en cuenta que en .net, la versión del ensamblado forma
parte de la clase, y no podrás hacer casting de una clase que implemente una
interface a una interface que provenga de un ensamblado distinto. ¿Entiendes
lo que te digo?.

Si realmente el interface proviene del mismo ensamblado, me gustaría
saberlo, por que realmente tengo curiosidad por entenderte.
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida