Eu tenho um bug muito estranho em nossa máquina de teste. O erro é:
System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from assembly 'ActiveViewers (...)' does not have an implementation.
Eu simplesmente não consigo entender o porquê. SetShort
existe na DummyItem
classe e recompilei uma versão com gravações no log de eventos apenas para garantir que não seja um problema de implantação / versão. O estranho é que o código de chamada nem chama o SetShort
método.
c#
.net
fusion
typeloadexception
Benjol
fonte
fonte
Respostas:
NOTA - Se essa resposta não ajudar, reserve um tempo para rolar para baixo pelas outras respostas que as pessoas adicionaram desde então.
Resposta curta
Isso pode acontecer se você adicionar um método a uma interface em um assembly e, em seguida, a uma classe de implementação em outro assembly, mas reconstruir o assembly de implementação sem fazer referência à nova versão do assembly de interface.
Nesse caso, DummyItem implementa uma interface de outro assembly. O método SetShort foi adicionado recentemente à interface e ao DummyItem - mas o assembly que contém DummyItem foi reconstruído com referência à versão anterior do assembly da interface. Portanto, o método SetShort está efetivamente presente, mas sem o molho mágico vinculando-o ao método equivalente na interface.
Resposta longa
Se você quiser reproduzir isso, tente o seguinte:
Crie um projeto de biblioteca de classes: InterfaceDef, adicione apenas uma classe e construa:
Crie um projeto de biblioteca de segunda classe: Implementação (com solução separada), copie o InterfaceDef.dll no diretório do projeto e adicione como referência de arquivo, adicione apenas uma classe e crie:
Crie um terceiro projeto de console: ClientCode, copie as duas DLLs no diretório do projeto, adicione referências de arquivo e adicione o seguinte código ao método Main:
Execute o código uma vez, o console diz "olá mundo"
Remova o comentário do código nos dois projetos da DLL e reconstrua - copie as duas DLL novamente no projeto ClientCode, reconstrua e tente executar novamente. TypeLoadException ocorre ao tentar instanciar o ImplementingClass.
fonte
Além do que a própria resposta do autor da pergunta já declarou, pode ser interessante notar o seguinte. O motivo para isso acontecer é porque é possível que uma classe tenha um método com a mesma assinatura que um método de interface sem implementar esse método. O código a seguir ilustra isso:
fonte
Eu obtive isso quando meu aplicativo não tinha uma referência a outro assembly definindo uma classe que o método na mensagem de erro usou. A execução do PEVerify deu um erro mais útil: "O sistema não consegue encontrar o arquivo especificado."
fonte
Me deparei com a mesma mensagem e aqui está o que descobrimos: Usamos dlls de terceiros em nosso projeto. Depois que um novo lançamento foi lançado, alteramos nosso projeto para apontar para o novo conjunto de dlls e compilado com sucesso.
A exceção foi lançada quando tentei instanciar uma de suas classes de interface durante o tempo de execução. Garantimos que todas as outras referências estivessem atualizadas, mas ainda sem sorte. Precisamos de um tempo para identificar (usando o Pesquisador de objetos) que o tipo de retorno do método na mensagem de erro era um tipo completamente novo de um assembly novo e não referenciado.
Adicionamos uma referência à montagem e o erro desapareceu.
fonte
Eu recebi esse erro no seguinte cenário.
var target = Assembly.GetAssembly(typeof(FertPin.Classes.Contact));
A correção para mim foi atualizar a referência System.Web.Mvc no assembly B para 4.0.0.0. Parece óbvio agora!
Graças ao pôster original!
fonte
A outra vez que você pode obter esse erro é se você tiver uma versão incorreta de um assembly assinado. Não é o sintoma normal para essa causa, mas aqui foi o cenário em que eu o peguei
um projeto asp.net contém o assembly A e o assembly B, B é fortemente nomeado
A montagem A usa Activator.CreateInstance para carregar a montagem C (ou seja, não há referência a C criada separadamente)
C foi construído referenciando uma versão mais antiga do assembly B do que está atualmente presente
espero que ajude alguém - levei anos para descobrir isso.
fonte
Eu também tive esse erro, que foi causado por um exe de Qualquer CPU que referenciava quaisquer assemblies de CPU que por sua vez referenciavam um assembly x86.
A exceção reclamou de um método em uma classe em MyApp.Implementations (Any CPU), que derivou MyApp.Interfaces (Any CPU), mas no fuslogvw.exe, encontrei uma exceção oculta de 'tentativa de carregar o programa com um formato incorreto' do MyApp .CommonTypes (x86), usado por ambos.
fonte
Continuo voltando a isso ... Muitas das respostas aqui explicam muito bem qual é o problema, mas não como solucioná-lo.
A solução para isso é excluir manualmente os arquivos bin no diretório publicado do seu projeto. Ele limpará todas as referências e forçará o projeto a usar as DLLs mais recentes.
Não sugiro usar a função Excluir das ferramentas de publicação, porque isso tende a desabilitar o IIS.
fonte
Eu tenho outra solução esotérica para essa mensagem de erro. Atualizei minha estrutura de destino do .Net 4.0 para 4.6 e meu projeto de teste de unidade estava me fornecendo o erro "System.TypeLoadException ... não possui uma implementação" quando tentei criar. Ele também deu uma segunda mensagem de erro sobre o mesmo método supostamente não implementado que dizia "A tarefa 'BuildShadowTask' falhou inesperadamente". Nenhum dos conselhos aqui pareceu ajudar, então procurei "BuildShadowTask" e encontrei uma postagem no MSDN que me levou a usar um editor de texto para excluir essas linhas do arquivo csproj do projeto de teste de unidade.
Depois disso, os dois erros desapareceram e o projeto foi construído.
fonte
Encontrei esse erro em um contexto em que estava usando o Autofac e muito carregamento dinâmico de assembly.
Ao executar uma operação de resolução de Autofac, o tempo de execução falha ao carregar um dos assemblies. A mensagem de erro reclamou isso
Method 'MyMethod' in type 'MyType' from assembly 'ImplementationAssembly' does not have an implementation
. Os sintomas ocorreram durante a execução em uma VM do Windows Server 2012 R2, mas não ocorreram nas VMs do Windows 10 ou Windows Server 2016.ImplementationAssembly
referenciadoSystem.Collections.Immutable
1.1.37, e continha implementações de umaIMyInterface<T1,T2>
interface, que foi definida em um separadoDefinitionAssembly
.DefinitionAssembly
referenciadoSystem.Collections.Immutable
1.1.36.Os métodos dos
IMyInterface<T1,T2>
quais "não foram implementados" tinham parâmetros do tipoIImmutableDictionary<TKey, TRow>
, definidos emSystem.Collections.Immutable
.A cópia real
System.Collections.Immutable
encontrada no diretório do programa era a versão 1.1.37. Na minha VM do Windows Server 2012 R2, o GAC continha uma cópia daSystem.Collections.Immutable
1.1.36. No Windows 10 e Windows Server 2016, o GAC continha uma cópia doSystem.Collections.Immutable
1.1.37. O erro de carregamento ocorreu apenas quando o GAC continha a versão mais antiga da DLL.Portanto, a causa raiz da falha na carga de montagem foram as referências incompatíveis
System.Collections.Immutable
. A definição e implementação da interface tinham assinaturas de métodos com aparência idêntica, mas na verdade dependiam de versões diferentes doSystem.Collections.Immutable
, o que significava que o tempo de execução não considerava a classe de implementação correspondente à definição da interface.A adição do seguinte redirecionamento de ligação ao meu arquivo de configuração do aplicativo corrigiu o problema:
fonte
System.Collections.Immutable
. No meu caso, não havia muitos outros parâmetros candidatos ou tipos de retorno no método afetado. Também me lembro de usar o ILSpy para inspecionar os metadados de dependência nas DLLs "DefinitionAssembly" e "ImplementationAssembly" compiladas, analisando especificamente as versões das referências.System.Net.Http
pacote, adicionei odependentAssembly
elemento e copiei as informações do ILSpy e ele está funcionando agora, o erro se foi!Eu consegui isso com uma dependência de projeto em forma de "diamante":
Recompilei o projeto A, mas não o Projeto B, o que permitiu que o Projeto B "injetasse" a versão antiga da dll do Projeto
fonte
Encontrei isso quando renomeei um projeto (e o nome do assembly), do qual dependia um projeto ASP.NET. Os tipos no projeto da web implementaram interfaces na montagem dependente. Apesar de executar o Clean Solution no menu Build, o assembly com o nome anterior permaneceu na
bin
pasta e quando meu projeto web foi executadoa exceção acima foi lançada, reclamando que os métodos de interface nos tipos de web de implementação não foram realmente implementados. A exclusão manual da montagem na
bin
pasta do projeto da web resolveu o problema.fonte
Também recebi esse erro quando havia ativado a Cobertura de código anteriormente durante o teste de unidade de um dos conjuntos. Por alguma razão, o Visual Studio "armazenou em buffer" a versão antiga dessa DLL específica, embora eu a tenha atualizado para implementar uma nova versão da interface. Desativar a cobertura de código se livrou do erro.
fonte
Este erro também pode ser causado se um assembly for carregado usando Assembly.LoadFrom (String) e estiver referenciando um assembly que já foi carregado usando Assembly.Load (Byte []).
Por exemplo, você incorporou os assemblies referenciados do aplicativo principal como recursos, mas seu aplicativo carrega plug-ins de uma pasta específica.
Em vez de usar o LoadFrom, você deve usar o Load. O código a seguir fará o trabalho:
fonte
Outra explicação para esse tipo de problema envolvendo C ++ gerenciado.
Se você tentar stub uma interface definida em um assembly criado usando C ++ gerenciado que tenha uma assinatura especial, você receberá a exceção quando o stub for criado.
Isso é verdade para o Rhino Mocks e provavelmente qualquer estrutura de simulação que use
System.Reflection.Emit
.A definição da interface obtém a seguinte assinatura:
Observe que o tipo C ++ é
long
mapeado paraSystem.Int32
(ou simplesmenteint
em C #). É o pouco obscuromodopt
que está causando o problema, como afirma Ayende Rahien na lista de discussão Rhino Mocks .fonte
System::Byte
. Mudei a assinatura para aceitar umunsigned short
e o céu estava azul novamente.Acabei de atualizar uma solução do MVC3 para o MVC5 e comecei a receber a mesma exceção do meu projeto de teste de unidade.
Verifiquei todas as referências à procura de arquivos antigos e, eventualmente, descobri que precisava fazer alguns bindingRedirects for Mvc, no meu projeto de teste de unidade.
fonte
No meu caso, ajudou a redefinir a caixa de ferramentas do WinForms.
Eu recebi a exceção ao abrir um
Form
no designer; no entanto, a compilação e a execução do código foram possíveis e o código se comportou conforme o esperado. A exceção ocorreu em um localUserControl
implementando uma interface de uma das minhas bibliotecas referenciadas. O erro surgiu após a atualização desta biblioteca.Isso
UserControl
foi listado na caixa de ferramentas do WinForms. Provavelmente, o Visual Studio mantinha uma referência em uma versão desatualizada da biblioteca ou estava armazenando em cache uma versão desatualizada em algum lugar.Aqui está como eu me recuperei dessa situação:
Reset Toolbox
menu de contexto. (Isso remove itens personalizados da caixa de ferramentas).No meu caso, os itens da caixa de ferramentas foram restaurados para o estado padrão; no entanto, a seta do ponteiro estava ausente na caixa de ferramentas.
No meu caso, o Visual Studio foi encerrado com uma exceção de violação e abortado.
Agora tudo está funcionando sem problemas.
fonte
FWIW, obtive isso quando havia um arquivo de configuração redirecionado para uma versão inexistente de um assembly referenciado. Registros de fusão para a vitória!
fonte
Eu recebi esse erro porque eu tinha uma classe em um assembly 'C' que estava na versão 4.5 da estrutura, implementando uma interface no assembly 'A' que estava na versão 4.5.1 da estrutura e servindo como classe base para o assembly 'B', que também estava na versão 4.5.1 da estrutura. O sistema lançou a exceção ao tentar carregar a montagem 'B'. Além disso, eu instalei alguns pacotes de nuget visando o .net 4.5.1 nos três assemblies. Por alguma razão, mesmo que as referências de pepitas não estivessem aparecendo no assembly 'B', ele foi criado com êxito.
O problema real era que os assemblies referenciavam versões diferentes de um pacote de pepitas que continham a interface e a assinatura da interface havia mudado entre as versões.
fonte
No meu caso, eu já havia mencionado um
mylib
projeto em uma pasta de irmãos fora do repositório - vamos chamar assimv1.0
.Mais tarde eu fiz isso corretamente e usei-o através de um submódulo git - vamos chamar assim
v2.0
. Um projeto,consoleApp
no entanto, não foi atualizado corretamente. Ainda fazia referência aov1.0
projeto antigo fora do meu projeto git.De maneira confusa , apesar de
*.csproj
estar claramente errado e apontandov1.0
, o Visual Studio IDE mostrou o caminho como ov2.0
projeto! F12 para inspecionar a interface e a classe também foram para av2.0
versão.A montagem colocada na pasta bin pelo compilador era a
v1.0
versão, daí a dor de cabeça.O fato de o IDE estar mentindo para mim tornou ainda mais difícil perceber o erro.
Solução : referências de projeto excluídas
ConsoleApp
e lidas.Dica geral: recompile todos os conjuntos do zero (sempre que possível, não é possível para pacotes de pepitas) e verifique os carimbos de data e hora na
bin\debug
pasta. Qualquer assembléia antiga é seu problema.fonte
Eu enfrentei quase o mesmo problema. Eu estava coçando a cabeça o que está causando esse erro. Eu cruzei, todos os métodos foram implementados.
No Google, consegui esse link entre outros. Com base no comentário de @Paul McLink, estas duas etapas resolveram o problema.
e o erro se foi .
Reinicie o VS Plugin
Obrigado Paul :)
Espero que isso ajude alguém que se deparar com esse erro :)
fonte
Eu também tive esse problema enquanto executava meus unittests. O aplicativo funcionou bem e sem erros. A causa do problema no meu caso foi que eu havia desligado a construção dos projetos de teste. Reativar a construção dos meus projetos de teste resolveu os problemas.
fonte
Vi isso no Visual Studio Pro 2008 quando dois projetos criaram assemblies com o mesmo nome, um da classe lib SDF.dll e um que referenciava a lib com o nome do assembly sdf.exe. Quando mudei o nome do assembly de referência, a exceção desapareceu
fonte
Isso significa simplesmente que o projeto de implementação está desatualizado nos meus casos. A DLL que contém a interface foi reconstruída, mas a dll de implementação ficou obsoleta.
fonte
Aqui está minha opinião sobre esse erro.
Adicionado um
extern
método, mas minha pasta estava com defeito. FoiDllImportAttribute
colocado em uma linha comentada.A garantia de que o atributo foi realmente incluído na fonte corrigiu o problema.
fonte
Eu recebi isso em um serviço WCF devido a ter um tipo de compilação x86 selecionado, fazendo com que os compartimentos permaneçam sob bin \ x86 em vez de bin. Selecionar Qualquer CPU fez com que as DLLs recompiladas fossem para os locais corretos (não entrarei em detalhes sobre como isso aconteceu em primeiro lugar).
fonte
Eu tive o mesmo problema. Eu descobri que minha montagem, que é carregada pelo programa principal, tinha algumas referências com "Copy Local" configurado como true. Essas cópias locais das referências estavam procurando outras referências na mesma pasta, que não existiam porque o "Copiar Local" de outras referências foi definido como falso. Após a exclusão das referências copiadas "acidentalmente", o erro desapareceu porque o programa principal foi configurado para procurar os locais corretos das referências. Aparentemente, as cópias locais das referências estragaram a sequência de chamadas, porque essas cópias locais foram usadas em vez das originais presentes no programa principal.
A mensagem levar para casa é que esse erro aparece devido ao link ausente para carregar a montagem necessária.
fonte
No meu caso, eu estava tentando usar
TypeBuilder
para criar um tipo.TypeBuilder.CreateType
lançou essa exceção. Acabei percebendo que precisava adicionarMethodAttributes.Virtual
os atributos ao chamarTypeBuilder.DefineMethod
um método que ajuda a implementar uma interface. Isso ocorre porque, sem esse sinalizador, o método não implementa a interface, mas um novo método com a mesma assinatura (mesmo sem especificarMethodAttributes.NewSlot
).fonte
Como um adendo: isso também pode ocorrer se você atualizar um pacote de pepitas usado para gerar um assembly falso. Digamos que você instale a V1.0 de um pacote de nuget e crie um assembly falso "fakeLibrary.1.0.0.0.Fakes". Em seguida, você atualiza para a versão mais recente do pacote nuget, digamos v1.1, que adicionou um novo método a uma interface. A biblioteca Fakes ainda está procurando a v1.0 da biblioteca. Simplesmente remova o conjunto falso e gere-o novamente. Se esse foi o problema, isso provavelmente o corrigirá.
fonte
Eu recebi esse erro após uma atualização recente do Windows. Eu tinha uma classe de serviço definida para herdar de uma interface. A interface continha uma assinatura que retornava um ValueTuple, um recurso relativamente novo em C #.
Tudo o que posso adivinhar é que a atualização do Windows instalou uma nova, mas mesmo referenciando-a explicitamente, atualizando redirecionamentos de ligação, etc ... O resultado final foi apenas alterar a assinatura do método para algo "padrão", acho que você poderia dizer.
fonte