Eu tenho um projeto auxiliar que eu uso em todos os aplicativos que eu crio. Ele contém alguns métodos de extensão e um monte de classes auxiliares genéricas, controles etc. Eu atualizo / estendo o projeto auxiliar periodicamente. Geralmente, esses são projetos pequenos e não relacionados, e eu sou a única pessoa trabalhando em todos eles.
Eu tentei duas abordagens para usá-lo
- adicione arquivos .cs diretamente (Adicionar como link) a cada projeto em que os uso
- compile-o como .dll e adicione-o como referência
Vejo alguns benefícios e desvantagens dessas abordagens.
O primeiro:
- é mais simples, porque as classes auxiliares são compiladas no arquivo exe, portanto, muitas vezes posso facilmente fornecer apenas um único arquivo .exe que funcionará bem. Como adiciono como link, posso ter certeza de que sempre que criar qualquer projeto que use o auxiliar, os arquivos auxiliares serão a versão mais recente.
- é ainda mais simples, porque eu posso separar os arquivos, para que meus métodos de extensão que funcionam bem no .NET 4.0 possam ser referenciados separadamente daqueles que exigem o .NET 4.5, o que significa que o aplicativo como um todo pode ser executado no .NET 4.0
- Permite depurar através do código, com todos os benefícios de pontos de interrupção etc etc ...
- não parece ser a "melhor prática"
O segundo:
- parece ser a abordagem correta, mas:
- requer que eu forneça um arquivo .dll separado, o que, por algum motivo, é muito mais difícil para os usuários (eles tendem a compartilhar meus programas sem o .dll, que falha na inicialização)
- como ele é compilado em uma única .dll, exigirá a versão mais alta do .NET - muitos dos meus usuários não possuem o .NET 4.5 e apenas alguns elementos da minha classe auxiliar o exigem, o que significa que posso forçar algumas pessoas atualizar seus sistemas sem motivo
- Também preciso garantir que, sempre que atualize qualquer um dos meus programas, também forneça o arquivo .dll - mesmo que eu não saiba se ele foi alterado desde a última versão ou não (poderia ter sido, mas poderia também ser a mesma versão). Não vejo uma maneira simples de determinar isso, sem acompanhar a versão da montagem, que é um trabalho adicional. Por enquanto, quando atualizo meus programas, apenas entrego exe atualizado e gosto de mantê-lo pequeno e discreto.
Então, qual é o benefício real de usar o arquivo .dll aqui? Observe que sou a única pessoa que edita o código de todos os aplicativos e arquivos auxiliares.
Além disso, para esclarecer - os aplicativos geralmente são muito pequenos, enquanto o código contido nas classes auxiliares é completamente genérico para todos eles (algumas simples comparações de strings, caminhos ou operações XML etc.)
Na verdade, alguém me fez perceber agora que há uma terceira opção. Como eu tenho o código auxiliar em um projeto separado, posso adicioná-lo às soluções de cada um dos meus aplicativos separados - que funciona como 'Adicionar como link' para arquivos únicos, exceto que eu adiciono apenas um único projeto ... Mas como observado pelo Doc Brown, isso significa essencialmente que .dll precisará ser adicionado ao projeto de qualquer maneira ...
No entanto, outra coisa que é a favor de não usar os arquivos DLL é a capacidade de depurar ativamente a classe auxiliar ...
Respostas:
Você já viu a maioria dos prós e contras. Usar arquivos cs como referências é realmente mais leve e geralmente mais fácil de gerenciar. No entanto, recomendo usar essa abordagem exclusivamente quando seus
cs
arquivos forem totalmente independentes e não tiverem requisitos de compilação especiais.Usando DLLs separadas
explicitará as dependências de outros utilitários ou bibliotecas (desde que você não possua essas dependências, funcionará bem)
permitirá definir configurações de compilação específicas (por exemplo, se uma classe funcionar apenas na configuração x86 ou precisar de pelo menos .NET 4.0, a configuração de compilação do assembly tornará esse requisito explícito).
Portanto, especialmente se você tiver muitos componentes independentes de classe única, usar a referência a arquivos é bom, mas se você tiver componentes que fazem referência a outros componentes ou requisitos específicos de compilação, recomendo o uso de DLLs.
Para atenuar os problemas com o gerenciamento de muitas DLLs separadas, você pode criar um pacote de instalação ou utilizar o ILMerge , que pode incorporar um conjunto de assemblies em um único executável. Em nosso ambiente, lidamos com o problema de maneira diferente, usando um script de implantação para cada aplicativo. Esse script garante que todas as DLLs necessárias sejam sempre entregues à produção quando uma nova versão do aplicativo for publicada.
fonte
As DLLs são úteis quando um aplicativo é grande e há partes que exigem atualizações, mas não o aplicativo inteiro. Portanto, se você estiver escrevendo o MS Word, é útil ter o código de verificação ortográfica em uma DLL que possa ser atualizada sem precisar atualizar todo o MS Word. Se o que você está escrevendo é um aplicativo utilitário pequeno (ou uma série de aplicativos independentes que usam todos o mesmo código), não faz muita diferença se o código está incorporado no (s) aplicativo (s) ou não.
fonte
Você resumiu bastante na sua pergunta, só tenho alguns pontos a acrescentar.
O Mono Options é um ótimo exemplo de pacote NuGet que usa muito bem a primeira abordagem.
Como alternativa, se você decidir usar dlls, poderá usar ferramentas como o Costura para incorporar essa referência no seu executável como um recurso incorporado. Para usá-lo basta adicionar o
Costura.Fody
pacote:fonte
Se uma dll é mais benéfica ou não depende de vários fatores:
O objetivo de uma biblioteca compartilhada é pegar o código comum a vários executáveis e centralizá-lo para que todos os executáveis compartilhem uma cópia. Isso tem como objetivo economizar espaço e facilitar a atualização do código.
Se a quantidade de código na sua classe auxiliar for muito pequena, pode não valer a pena movê-la para uma dll, pois a sobrecarga do código em uma dll pode neutralizar o benefício de economia de espaço em tê-la centralizada.
Além disso, se você estiver criando apenas alguns executáveis, o tamanho do código em cada executável pode ser pequeno o suficiente para não ser um problema. No entanto, quanto mais executáveis você tiver usando o mesmo código, mais benéfico seria migrar o código para uma dll.
Como um exemplo simplificado, digamos que sua classe auxiliar compila até 128 bytes em um arquivo exe, mas quando movida para uma dll, a dll é de 512 bytes. Se você tiver apenas três executáveis, estará economizando espaço incluindo o código nos executáveis. No entanto, se você tivesse 5 executáveis, estaria no ponto em que seria melhor ter uma dll porque o espaço combinado ocupado por 5 cópias do código (5 * 128 = 640 bytes) é maior que o espaço ocupado tendo o código em uma dll (512 bytes).
Agora diga, por exemplo, que você encontrou um bug no seu código auxiliar. Se você compilou todos os seus executáveis com o código inserido, precisará recompilar todos os executáveis e redistribuir as versões recompiladas. Se você compilasse o código em uma DLL, seria necessário recompilar e redistribuir apenas uma DLL, e o bug seria corrigido automaticamente para todos os executáveis que a utilizassem.
Por fim, para que um programa encontre uma dll, é necessário saber onde procurar a dll. Se você estiver mantendo todos os seus executáveis juntos, basta colocar a dll no mesmo diretório e todos encontrarão imediatamente. Se você intencionalmente mantê-los separados, fica mais difícil coordená-los para usar a mesma dll.
fonte
Sua terceira opção é a mais apropriada (adicione-a como um projeto "biblioteca de classes" separado à solução). Isso combina os benefícios de todas as abordagens:
Fazemos isso o tempo todo e não posso fazer nada além de recomendar essa abordagem.
Outra quarta alternativa que você não mencionou é colocá-lo em um repositório privado do NuGet, que permitiria a versão correta e a referência sem o projeto extra em cada solução.
fonte
Como desenvolvedor, eu sempre gosto de incluir a referência da solução do utilitário para o meu aplicativo, pois isso me permite depurar o código (e detectar possíveis erros no Utility também!), Além de quaisquer alterações feitas no utilitário, que são automaticamente incluídas no aplicativo.
Portanto, na verdade, a decisão depende de quão maduro é o utilitário ! Se você não tiver certeza sobre os bugs do Utility, deve sempre incluir o arquivo .cs desse utilitário para descobrir os bugs. Mas se tiver certeza de que o Utility está maduro o suficiente e não retornará resultado com nenhum bugs Como não há escopo para aprimoramento no utilitário, você pode prosseguir e incluir o arquivo DLL.
fonte