Альтернативы ключевому слову "using" в C #? - PullRequest
5 голосов
/ 10 сентября 2009

Я только что закончил смотреть эпизод с Бобом Мартином в NDC, где он сказал, что использование директив в C # в верхней части страницы плохо из-за сильной связи, которую они создают / подразумевают между компонентами.

Как можно использовать внешние .dll без добавления ссылки на проект и оператора использования?

Я помню V6, который раньше позволял вам создавать объект по строке ProgId - я не уверен, что это техника, которую я ищу, но это пример языка, который не нуждался в ссылке на проект использовать DLL.

РЕДАКТИРОВАТЬ: Вот ссылка на конференцию . Извините, у меня нет точной цитаты или минуты в презентации, я иду по памяти.

Ответы [ 5 ]

7 голосов
/ 10 сентября 2009

Я считаю, что Боб Мартин на самом деле имеет в виду раннее связывание, а не позднее.

Позднее связывание в .NET возможно посредством отражения и, в частности, класса Activator, который позволяет создавать тип во внешней сборке с использованием имени файла или имени сборки.

Обычно, используя директивы (не оператор using), идут рука об руку с прямой ссылкой на внешнюю сборку. то есть. Вы добавляете ссылку на сборку, а затем добавляете директивы using, чтобы избежать необходимости вводить полную иерархию пространства имен при использовании внешних типов.

Так что, если вы обнаружите, что ваш код имеет большое количество директив использования в верхней части, возможно, что вы ссылаетесь на многие другие типы напрямую и, таким образом, увеличиваете связь / зависимость вашего кода от этих типов.

Полагаю, именно поэтому Боб называет их плохими. Ответ на вопрос "это на самом деле плохо?" является очень субъективным и контекстно-зависимым.

В целом расцепление компонентов почти всегда является хорошей целью при разработке программного обеспечения. Это потому, что это позволяет вам изменять части вашей системы с минимальным воздействием на остальную часть системы. Прочитав одну или две книги Боба Мартинса, я ожидал, что это то, к чему он стремится.

6 голосов
/ 10 сентября 2009

Плохо не само выражение using, а если вы получите слишком много из них.

Такое выражение, как using System;, само по себе редко является проблемой, но если у вас есть много (я бы сказал, больше 3-6, в зависимости от того) в одном и том же кодовом файле, это может быть индикация жесткой связи .

Вы также можете применить аналогичное эмпирическое правило к количеству ссылок в самом проекте.

Решением для тесной связи является программирование для интерфейсов и Dependency Injection (DI).

ProgId - способ, который вы помните из VB, - это просто COM в действии. По сути, вы использовали этот ProgId для получения ссылки на экземпляр, который реализовал желаемый интерфейс. Недостатком было то, что это работало только тогда, когда COM-объект был зарегистрирован повсеместно. Помните дьявольский ад?

Вы по-прежнему можете применять тот же принцип, используя определенные разновидности DI, только теперь интерфейс имеет тип .NET и не определен в IDL, и вам нужен какой-то DI-контейнер для обеспечения конкретной реализации.

6 голосов
/ 10 сентября 2009

using - это просто ярлык к пространствам имен, они не являются ссылками на внешние файлы. Поэтому это просто не имеет смысла.

В любом случае, то, что можно сделать, - это иметь интерфейсную DLL (DLL только с интерфейсами), чтобы вы динамически загружали и использовали различные сборки и создавали типы (через отражение), которые вы можете приводить к известным интерфейсам. Это правильный способ ослабления внешних ссылок при сохранении преимуществ строго типизированного языка и раннего связывания.

Посмотрите классы Assembly и AppDomain для загрузки сборок и Activator для создания экземпляров типов по имени.

2 голосов
/ 10 сентября 2009

Вы можете использовать отражение:

// 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]);
1 голос
/ 10 сентября 2009

Вы можете делать то, что вы имеете в виду, с помощью отражения. Вы можете загрузить сборку во время выполнения и просмотреть ее, чтобы получить классы и т. Д. И вызывать их динамически.

Лично я бы не стал этого делать, чтобы избежать связи. Для меня это плохое использование рефлексии, и я бы предпочел добавить его в проект и ссылаться на него, если только нет особой причины, почему бы не сделать это. Отражение увеличивает нагрузку на систему, и вы не получаете преимущества безопасности при компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...