Pergunta

Acabei de assistir um episódio de Bob Martin em NDC onde ele disse "usando" directivas em C # no topo de uma página são ruins por causa do apertado acoplamento eles criam / implicam entre componentes.

O que maneira estão lá para usar .dlls externos sem adicionar uma referência de projeto e uma usando declaração?

Eu me lembro V6 usado para permitir que você criar um objeto pela cadeia do ProgId - não tenho certeza que é a técnica que eu estou procurando, mas é um exemplo de uma linguagem que não precisava de uma referência de projeto para usar uma dll.

EDIT: Aqui está um link para a conferência . Desculpe eu não tenho a cotação ou minuto no presenation, eu vou pela memória.

Foi útil?

Solução

Não é o utilizando-se instrução que é ruim -. É se você começar muitos deles

Uma declaração como using System; raramente é um problema em si, mas se você tiver lotes (eu diria que mais de 3-6, dependendo de quais) no mesmo arquivo de código, que poderia ser um indicação de acoplamento forte .

Você poderia muito bem aplicar uma regra semelhante de ouro para o número de referências em um projeto em si.

A solução para acoplamento forte é programação para as interfaces e Dependency Injection (DI).

A forma ProgId de fazer as coisas que você pode se lembrar de VB era simplesmente COM em ação. Em essência, você usou que ProgId para obter uma referência a uma instância que implementou a interface desejada. A desvantagem foi que isso só funcionou quando o objeto COM foi universalmente registrado. Lembre-se dll inferno?

Você ainda pode aplicar o mesmo princípio usando certos sabores de DI, apenas que agora a interface é um tipo .NET e não definidos no IDL, e você precisa de algum tipo de DI Container para fornecer a implementação concreta.

Outras dicas

Eu acredito que Bob Martin é realmente referindo-se precoce versus ligação tardia.

Em .NET ligação tardia é possível através de reflexão e, mais especificamente, a classe Activator que permite a criação de um tipo em uma montagem externa usando um nome ou nome de assemblagem.

Normalmente, usando diretivas (não utilizando a instrução) andam de mãos dadas com referência direta um assembly externo. ie. Você adicionar uma referência a uma montagem e, em seguida, adicionar usando diretivas para evitar a necessidade de digitar a hierarquia namespace completo quando você usa os tipos externos.

Então, se você encontrar o seu código tem um grande número de diretivas usando na parte superior, é possível que você está fazendo referência muitos outros tipos diretamente e assim aumentar o acoplamento / dependência do seu código sobre esses tipos.

Eu acho que é por isso que Bob está se referindo a eles como ruim. A resposta para a pergunta "é este realmente ruim?" é muito subjetiva e dependente do contexto.

No entanto geral, de-acoplamento de componentes é quase sempre uma boa meta ter como objectivo na concepção de software. Isso é porque ele permite que você altere partes de seu sistema com o mínimo impacto sobre o resto do sistema. Depois de ler um ou dois livros Bob Martins, eu esperaria que isso é o que ele está chegando.

using é apenas um atalho para namespaces, eles não são referências a arquivos externos. Portanto, este não é apenas realmente fazendo sentido.

De qualquer forma, o que se pode fazer é ter uma DLL de interface (a DLL com apenas interfaces), para que você dinamicamente carregar e usar diferentes montagens e criar tipos (por meio de reflexão) que você pode lançar para as interfaces bem conhecidos. Esta é a maneira correta de afrouxamento referências externas, mantendo os benefícios da linguagem fortemente digitado e ligação antecipada.

Tenha um olhar para o Assembléia AppDomain aulas para conjuntos de carga, e Activator para criar instâncias do tipo pelo nome.

Você pode usar reflexão:

// Load the assembly
Assembly assembly = Assembly.LoadFrom(@"c:\path\Tools.dll");
// Select a type
Type type = assembly.GetType("Tools.Utility");
// invoke a method on this type
type.InvokeMember("SomeMethod", BindingFlags.Static, null, null, new object[0]);

Você pode fazer o que você está se referindo por meio de reflexão. Você pode carregar o assembly em tempo de execução, e refletir através dele para obter as classes etc. e chamá-los de forma dinâmica.

Pessoalmente, eu não faria isso, porém ao acoplamento evitar. Para mim, isso é um mau uso da reflexão, e eu seria muito melhor adicioná-lo ao projeto e referenciá-lo, a menos que haja uma razão específica por que não fazê-lo. Reflexão adiciona sobrecarga para o sistema, e você não terá a vantagem de segurança tempo de compilação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top