2010-09-07 5 views
11

Y at-il un moyen d'obtenir l'assembly qui contient une classe avec le nom TestClass? Je connais juste le nom de la classe, donc je ne peux pas créer une instance de ça. Etobtenir l'assemblage par nom de classe

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

ne fonctionnait pas pour moi.

+3

L'itération sur tous les assemblages référencés serait votre seule option, mais elle entraînerait également facilement des doublons. Mais je ne crois pas que ce soit toutes les informations que vous avez, alors vous devriez essayer d'être plus explicite sur votre raisonnement pour votre question. –

Répondre

16

De l'Type objectType dans la question, je suppose que vous êtes en fait après le type par nom (pas l'assemblée); si en supposant l'ensemble est chargé et le nom du type est unique, LINQ peut aider:

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); 

Cependant, il peut être préférable de travailler avec le nom qualifié d'assembly au lieu du nom du type.

+0

Impossible de charger un ou plusieurs types demandés. Récupérez la propriété LoaderExceptions pour plus d'informations. – Soonts

+1

@Soonts - semble-t-il qu'il existe peut-être une dépendance dans un assembly qui manque? –

21
Assembly asm = typeof(TestClass).Assembly; 

vous obtiendrez l'assemblage tant qu'il est référencé. Dans le cas contraire, vous devez utiliser un nom complet:

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 fait, la connaissance de classname est suffisante dans la plupart des scénarios. MSDN dit - Si le type est dans l'assembly en cours d'exécution ou dans Mscorlib.dll, il suffit de fournir le nom de type qualifié par son espace de noms.

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

Si vous ne connaissez pas l'assemblage de type contenant (bien que je ne peux pas imaginer pourquoi) -

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

La seule restriction - assemblage contenant TestClass aurait dû être déjà chargé au moment d'appeler ce code .

J'espère que cela vous aidera. :) La réponse de

2

Marc est vraiment bon, mais comme il était trop lent (j'utilise cette méthode souvent), je décide d'aller avec une approche différente:

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]; 
    } 

Vous pouvez gérer le conflit de noms comme vous voulez, mais dans cet exemple j'ai décidé d'ignorer les suivants.

Questions connexes