Hot-patching de um servidor: carregando dinamicamente os tipos de um conjunto enviado

5

No projeto atual em que estou trabalhando, algumas classes C # estão sendo armazenadas como código-fonte nos registros de banco de dados do SQL Server e executadas conforme necessário usando CSScript . Isso está sendo feito para que o servidor não precise ser removido para substituir o assembly em que essas classes residem.

Embora isso parecesse uma boa idéia em princípio, os custos desse esquema excederam os benefícios em vários níveis, e agora estou buscando outros possíveis remédios.

No passado, quando eu precisava desse tipo de "ligação tardia", eu simplesmente usei Activator.CreateInstance() para instanciar e usar os tipos de que preciso. Em geral, ocultarei essa funcionalidade por trás de um método de fábrica que usa um arquivo de configuração XML para conectar os assemblies apropriados.

Portanto, no meu mundo perfeito, quando eu quiser fazer hot patch no servidor, vou copiar o assembly para o servidor, editar o arquivo XML para fazer referência ao novo assembly e, em seguida, na próxima vez que instâncias desses tipos forem solicitadas via o método de fábrica, o servidor receberá automaticamente instâncias do novo assembly em vez do antigo.

Dito isto, nunca tentei isso com um sistema em execução. Eu sempre usei isso com um programa que não está rodando, como uma espécie de sistema de plugins de um homem pobre. Estou ciente de coisas como MEF , mas não sabe como o MEF se aplica aqui, desde que eu nunca tive que usá-lo.

Minha pergunta é simples: o que estou perdendo? Isso não é tão simples quanto eu acho que é? Isso falhará porque eu não descarreguei o domínio do aplicativo que a DLL original da qual o tipo original foi carregado? Meu algoritmo se tornará de repente Skynet sem aviso?

Em suma, existe uma maneira melhor?

    
por Robert Harvey 14.07.2015 / 22:16
fonte

1 resposta

3

Dependendo do que você está tentando fazer, é mais simples.

O IIS reiniciará automaticamente seu pool de aplicativos quando perceber que um arquivo foi alterado. Se tudo o que você deseja fazer é corrigir um servidor em execução, basta enviar uma nova dll e deixar o ciclo do pool de aplicativos.

Will this fail because I haven't unloaded the app domain that the original DLL from which the original type was loaded?

Se sua DLL antiga e sua nova DLL tiverem a mesma versão, tenho certeza de que elas farão coisas muito ruins. Embora eu ache que tipos com o mesmo nome totalmente qualificado, mas versões diferentes, seriam compatíveis, parece que não é o caso .

what am I missing?

Uma coisa a se preocupar é que o carregamento a partir da configuração tende a ser uma operação cara - uma que é armazenada em cache, seja pelo seu código ou por alguma API subjacente. Confiar na fábrica para ver o novo alvo é provavelmente uma fonte rápida e fácil de bugs sutis. Há também problemas de simultaneidade em que seu código pode assumir que chamadas consecutivas para Factory.Create retornam o mesmo tipo de concreto.

Mas no final, isso se resumirá a Activator.CreateInstance .

    
por 14.07.2015 / 22:50
fonte