2010-09-07 8 views
11

Gibt es eine Möglichkeit, die Assembly zu erhalten, die eine Klasse mit dem Namen TestClass enthält? Ich kenne nur den Klassennamen, deshalb kann ich keine Instanz erstellen. UndAssemblierung nach Klassenname

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

hat nicht für mich funktioniert.

+3

Das Iterieren über alle referenzierten Assemblies wäre Ihre einzige Option, es würde jedoch leicht zu Duplikaten führen. Aber ich glaube nicht, dass das alles Informationen sind, die du hast, also solltest du versuchen, deine Argumentation für deine Frage deutlicher zu machen. –

Antwort

16

Vom Type objectType in der Frage, ich nehme an, Sie sind tatsächlich nach dem Typ nach Namen (nicht die Versammlung); so die Baugruppe geladen und der Typname ist einzigartig unter der Annahme, kann LINQ helfen:

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

Jedoch kann es besser sein, mit dem Assembly qualifizierten Namen zu arbeiten, anstelle des Typennamen.

+0

Ein oder mehrere der angeforderten Typen konnten nicht geladen werden. Rufen Sie die LoaderExceptions-Eigenschaft für weitere Informationen auf. – Soonts

+1

@Soons - klingt wie vielleicht gibt es eine Abhängigkeit in einer Baugruppe, die fehlt? –

21
Assembly asm = typeof(TestClass).Assembly; 

erhalten Sie die Assembly, solange es referenziert wird. Andernfalls würden Sie einen voll qualifizierten Namen verwenden müssen:

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

Tatsächlich ist die Kenntnis des Klassennamens in den meisten Szenarien ausreichend. MSDN sagt - Wenn der Typ sich in der gerade ausgeführten Assembly oder in Mscorlib.dll befindet, reicht es aus, den Typnamen anzugeben, der durch seinen Namespace qualifiziert ist.

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

Im Fall müssen Sie nicht die Baugruppe enthält Art kennen (obwohl ich, warum sich vorstellen kann nicht) -

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

Die einzige Einschränkung - Baugruppe enthält Testclass bereits im Moment des Aufrufs solchen Code geladen werden sollte .

Hoffe, das wird helfen. :)

2

Marcs Antwort ist wirklich gut, aber da es zu langsam war (ich diese Methode oft bin mit), entschied ich mich mit einem anderen Ansatz zu gehen:

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

Sie den Zusammenprall Namen verarbeiten kann so wie du es willst, aber in diesem Beispiel habe ich beschlossen, die folgenden zu ignorieren.