Como obter C # .Net Assembly por nome?

90

Existe algo como:

AppDomain.CurrentDomain.GetAssemblyByName("TheAssemblyName")

então, em vez de fazer um loop AppDomain.CurrentDomain.GetAssemblies(), poderíamos apenas obter o assembly específico diretamente.

Jronny
fonte

Respostas:

107

Você já tentou olhar para Assembly.Load (...) ?

cibernético
fonte
6
Para quem está se perguntando, isso joga System.IO.FileNotFoundExceptionse a montagem não pôde ser carregada.
Rudey
74

Resolvi com LINQ

Assembly GetAssemblyByName(string name)
{
    return AppDomain.CurrentDomain.GetAssemblies().
           SingleOrDefault(assembly => assembly.GetName().Name == name);
}
Fabio
fonte
8
Isso só funcionará se a montagem em questão estiver carregada. Pode não ajudar ao registrar tipos em um DAL de uma API da Web
Chazt3n
17

Depende do que você está tentando realizar.

Se você deseja apenas obter o assembly, deve chamar System.Reflection.Assembly.Load()(como já apontado). Isso ocorre porque o .NET verifica automaticamente se o assembly já foi carregado no AppDomain atual e não o carrega novamente se tiver sido.

Se você está apenas tentando verificar se o assembly foi carregado ou não (por algum motivo de diagnóstico, talvez), você precisa fazer um loop em todos os assemblies carregados.

Outro motivo pelo qual você pode querer fazer um loop é se você conhece apenas algumas das informações do assembly (por exemplo, não tem certeza da versão). Ou seja, você sabe o suficiente para "reconhecê-lo quando vê", mas não o suficiente para carregá-lo. Esse é um cenário bastante obscuro e improvável, no entanto.

EMP
fonte
System.Reflection.Assembly.Load () é tão perfeito quanto o que eu preciso.
Jronny
9

Para quem precisa apenas acessar os metadados do assembly (versão, etc.) verifique o Assembly.ReflectionOnlyLoad (nome), que é capaz de carregar apenas os metadados, possivelmente economizando na memória e no IO.

Mathieu Frenette
fonte
2
@ erik-reppen: De acordo com os documentos da MS, está disponível em versões anteriores. Estou usando em um aplicativo 3.5: msdn.microsoft.com/en-us/library/0et80c7k(v=vs.100).aspx
codenheim
7

Se esta é uma montagem que você referenciou, eu gosto de escrever uma classe como a seguinte:

namespace MyLibrary {
   public static class MyLibraryAssembly {
      public static readonly Assembly Value = typeof(MyLibraryAssembly).Assembly;
   }
}

e então sempre que você precisar de uma referência a esse assembly:

var assembly = MyLibraryAssembly.Value;
Dave Cousineau
fonte
Esta é uma solução muito limpa que sempre procuro! Posso usá-lo assim:options.RegisterFromAssembly(Application.AssemblyReference.Value)
Alielson Piffer
3

Você pode escrever um método de extensão que faça o que você precisa.

Este método enumera apenas assemblies carregados , se você possivelmente precisar carregá-lo, use a Assembly.Loadpartir da resposta aceita.

public static class AppDomainExtensions
{
    public static Assembly GetAssemblyByName(this AppDomain domain, string assemblyName)
    {
        return domain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == assemblyName);
    }
}

Então você chama este método em um AppDomain assim:

Assembly a = AppDomain.CurrentDomain.GetAssemblyByName("SomeAssembly")

Se SomeAssembly for carregado no AppDomain atual, o método o retornará, caso contrário, ele retornará null.

Marcell Toth
fonte
Não encontrei GetAssemblyByName ()
Ziggler
2

Dê uma olhada na classe System.Reflection.Assembly, em particular no método Load: MSDN

Maximilian Mayerl
fonte