2010-09-07 27 views
11

¿Hay alguna manera de obtener el ensamblado que contiene una clase con el nombre TestClass? Solo conozco el nombre de la clase, así que no puedo crear una instancia de eso. Yobtener el ensamblaje por nombre de clase

Type objectType = assembly.GetType("TestClass"); 

no funcionó para mí.

+3

La iteración de todos los ensamblados a los que se hace referencia sería su única opción, pero también resultaría fácilmente en duplicados. Pero no creo que esa sea toda la información que tiene, por lo que debe tratar de ser más explícito sobre su razonamiento para su pregunta. –

Respuesta

16

Desde el Type objectType en la pregunta, supongo que es en realidad después del tipo por su nombre (no el montaje); así suponiendo el conjunto está cargado y el nombre del tipo es único, LINQ pueden ayudar:

Type objectType = (from asm in AppDomain.CurrentDomain.GetAssemblies() 
        from type in asm.GetTypes() 
        where type.IsClass && type.Name == "TestClass" 
        select type).Single(); 
object obj = Activator.CreateInstance(objectType); 

Sin embargo, puede ser mejor trabajar con el nombre de ensamblado-cualificada en lugar del nombre del tipo.

+0

No se pueden cargar uno o más de los tipos solicitados. Recupere la propiedad LoaderExceptions para obtener más información. – Soonts

+1

@Soonts: ¿suena como que tal vez hay una dependencia en un ensamblaje que falta? –

21
Assembly asm = typeof(TestClass).Assembly; 

le conseguirá el conjunto, siempre que se haga referencia a él. De lo contrario, tendría que utilizar un nombre completo:

Assembly asm = null; 
Type type = Type.GetType("TestNamespace.TestClass, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); 
if (type != null) 
{ 
    asm = type.Assembly; 
} 
3

En realidad, el conocimiento de nombre de clase es suficiente en la mayoría de los escenarios. MSDN dice: si el tipo está en el ensamblado que se está ejecutando actualmente o en Mscorlib.dll, es suficiente proporcionar el nombre de tipo calificado por su espacio de nombre.

Type neededType = Type.GetType("TestClass"); //or typeof(TestClass) 
Assembly a = neededType.Assembly; 

En caso de que usted no sabe el tipo de montaje que contiene (aunque no puedo imaginar por qué) -

Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
Asssembly result = assemblies.FirstOrDefault(a=>a.GetType("TestClass",false)!=null); 

La única restricción - conjunto que contiene TestClass debería haber sido ya cargado en el momento de llamar a dicho código .

Espero que esto ayude. :) respuesta

2

de Marc es muy buena, pero ya que era demasiado lento (estoy usando ese método a menudo), me decidí a ir con un enfoque diferente:

private static Dictionary<string, Type> types; 
    private static readonly object GeneralLock = new object(); 

    public static Type FindType(string typeName) 
    { 
     if (types == null) 
     { 
      lock (GeneralLock) 
      { 
       if (types == null) 
       { 
        types = new Dictionary<string, Type>(); 
        var appAssemblies = AppDomain.CurrentDomain.GetAssemblies(); 
        foreach (var appAssembly in appAssemblies) 
        { 
         foreach (var type in appAssembly.GetTypes()) 
          if (!types.ContainsKey(type.Name)) 
           types.Add(type.Name, type); 
        } 
       } 
      } 
     } 

     return types[typeName]; 
    } 

usted puede manejar el conflicto de nombres de la manera que desee, pero en este ejemplo decidí simplemente ignorar los siguientes.

Cuestiones relacionadas