una que programacion poo objetos objeto metodos listas lista instanciar inicializador inicializacion declarar crear como clase c# .net reflection configuration

c# - que - Crea un objeto sabiendo solo el nombre de la clase?



objeto de objetos c# (5)

(I will not be loading a type from outside this assembly/namespace)

debido a la línea anterior, es seguro asumir que usted sabe lo que es el espacio de nombres. ¿No podrías hacer algo como esto?

Type t = Type.GetType("Namespace." + className); BaseClass c = Activator.CreateInstance(t) as BaseClass;

Si espera posiblemente poder agregar clases de estrategia adicionales para ser cargadas en el futuro, quizás a través de un ensamblaje adicional, necesitaría calificar completamente su nombre de clase. Esto se recomienda de todos modos, ya que podría proporcionar ampliabilidad mejorada para su aplicación.

Tengo un conjunto de clases, cada una es una estrategia diferente para hacer el mismo trabajo.

namespace BigCorp.SuperApp { public class BaseClass { } public class ClassA : BaseClass { } public class ClassB : BaseClass { } }

La elección de qué estrategia usar es configurable. Quiero configurar solo el nombre de clase ''ClassB'' en lugar del nombre de tipo completo ''BigCorp.SuperApp.ClassB'' en el archivo app.config.

<appConfig> <SuperAppConfig> <Handler name="ClassB" /> </SuperAppConfig> </appConfig>

Sin embargo, las llamadas de reflexión fallan porque esperan el nombre de tipo completo, particularmente

Type t = Type.GetType("ClassB"); // results in t == null BaseClass c = Activator.CreateInstance(t) as BaseClass; // fails

¿Cómo puedo hacer que esto funcione mientras configuro solo el nombre de clase? Concatenar el espacio de nombre para el nombre de clase para el nombre de tipo completo? ¿Hay alguna otra llamada de reflexión que funcione?

Si cree que esto es inútil y debería esperar que la configuración contenga el nombre completo, ¡estoy abierto a esa solución! Solo proporcione la razón para convencerme.

(No cargaré un tipo desde fuera de este ensamblado / espacio de nombres)


Utilice el nombre calificado para el ensamblaje o agárrese del ensamblado y use Assembly.GetType(name) . En este caso, dado que desea los tipos en el archivo de configuración, la calificación de ensamblaje es un camino válido, pero dado que sabe que todos sus tipos están en el mismo ensamblaje:

Assembly assembly = typeof(SomeKnownType).Assembly; // in the same assembly! Type type = assembly.GetType(name); // full name - i.e. with namespace (perhaps concatenate) object obj = Activator.CreateInstance(type);

El Type.GetType(string) estático tiene reglas de sondeo que a menudo causan confusión ... se ve en el ensamblado de la llamada y en algunos ensambles del sistema, pero no en todos los ensamblados cargados.


Como sabe que todas las clases provienen del mismo espacio de nombres, configúrelo una vez y úselo:

<appConfig> <SuperAppConfig handlerNamespace="BigCorp.SuperApp"> <Handler class="ClassB" /> </SuperAppConfig> </appConfig>

Editar: Cambié el nombre a clase para denotar mejor el significado de ese atributo.


Voy con el nombre de tipo completo en la configuración de la aplicación. A continuación se muestra un ejemplo un poco más completo, pero aún trivial

<SuperAppConfig> <ObjectConfig provider="BigCorp.SuperApp.ClassA"> <add name="one" /> <add name="two" /> </ObjectConfig> </SuperAppConfig>

Y la clase de fábrica que realmente crea esto

private static Assembly a = typeof(IFactoryObject).Assembly; public static IFactoryObject CreateObject(String providerName) { Type t = a.GetType(providerName) IFactoryObject o = Activator.CreateInstance(t) as IFactoryObject; return o; }


BaseClass c = Activator.CreateInstance(t) as BaseClass; // fails

También podría resultar del hecho de que CreateInstance no devuelve una instancia de BaseClass, en lugar de una instancia de BaseClass envuelta en un ObjectHandle.

Eche en su BaseClass después de usar el método UnWrap.