Могу ли я установить зависимость между пространствами имен в C #

Могу ли я ограничить классы из определенного пространства имен от ссылок на классы в другом конкретном пространстве имен? Оба пространства имен существуют в одной сборке .NET.

Пример:

namespace LegacyCode
{
    class LegacyClass { ... }
}

namespace NewCode
{
    class NewClass {...}
}

Я не хочу, чтобы классы из NewCode могли ссылаться на классы из LegacyCode.

Опции:

  1. Иметь разные сборки (усложняет развертывание, сборка занимает больше времени)
  2. Использование такого инструмента, как NDetect (стоит денег!)

У кого-нибудь есть другие идеи?


person GarethOwen    schedule 20.07.2010    source источник


Ответы (5)


Попробуйте пометить классы с помощью устаревшего атрибута. Это приведет к тому, что любой код, который сам не помечен как «Устаревший», будет генерировать предупреждение во время компиляции.

Включите параметр «Обрабатывать предупреждения как ошибки» на вкладке «Сборка» файла проекта, чтобы это предупреждение приводило к сбою компиляции с ошибкой.

Редактировать:

Согласитесь, что отдельные сборки - это хорошая стратегия для облегчения постепенного исчезновения этого кода. Однако это не остановит людей ссылаться на него. Атрибут obsolete дает понять, что этот код, ммм, устарел.

Редактировать # 2:

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

person MPritchard    schedule 20.07.2010
comment
Один из перегруженных конструкторов ObsoleteAttribute класса принимает параметр bool, определяющий, будут ли ссылки к отмеченному классу должны вызывать ошибки компиляции. - person Dan Tao; 20.07.2010
comment
Спасибо, Дэн, я никогда раньше этого не замечал! - person MPritchard; 20.07.2010

Задокументируйте дизайн, поговорите с людьми, просмотрите код. Не пытайтесь использовать технологии в решении проблем людей. (Тем не менее, часть обзора может стать более эффективной с такими инструментами, как NDetect.)

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

person Pontus Gagge    schedule 20.07.2010
comment
В принципе, я думаю, что вы правы - и это наше текущее решение (сообщить правило). Но на практике это не сработало. Опытный разработчик зарегистрировался в новом классе, который сломал зависимость - и рецензент тоже его пропустил. Вот почему я хочу более строгий способ контролировать это. - person GarethOwen; 20.07.2010
comment
Рад слышать! Я думаю, вам придется перекусить и согласиться с расходами либо в виде отдельного управления сборкой, либо в инструментах принудительного применения зависимостей. Мне неизвестны бесплатные альтернативы NDepend (и уж точно не с его набором функций). Но устранение зависимости будет стоить вам денег, особенно если техническое обслуживание будет продолжаться в течение нескольких лет - предварительные вложения для предотвращения последующего технического долга звучат предпочтительнее. - person Pontus Gagge; 20.07.2010

Я думаю, что отдельные сборки - единственно возможное решение.

person Incognito    schedule 20.07.2010

MS использует атрибут System.ObsoleteAttribute для отметки устаревшего / устаревшего кода. Этот атрибут предоставляет ctor, который создает ошибку компилятора. Хотя я бы использовал это, если унаследованных классов не так много.

person Florian Reischl    schedule 20.07.2010
comment
Я не знал об атрибуте «Устаревшее» - звучит неплохо. Но, к сожалению, у нас есть много унаследованных классов :( - person GarethOwen; 20.07.2010
comment
Поверьте, потратить послеобеденное время на копирование и вставку [Устарело] того стоит. Если ваш код должным образом разложен по папкам, поэтому весь устаревший код находится в одной папке, попробуйте найти и заменить с помощью Regex в Visual Studio. Я предполагаю, что вы захотите применить это к классам, перечислениям и структурам. - person MPritchard; 20.07.2010
comment
Босс не очень доволен тем, что 90% нашей базы кода помечены как устаревшие. - person GarethOwen; 20.07.2010
comment
Я согласен с вами MPritch. Возможно, я напишу свой собственный атрибут, который будет делать то же самое, что и «Устаревший», но с более дружелюбным именем. - person GarethOwen; 20.07.2010
comment
Устаревший - это просто другое слово для обозначения устаревшего, не так ли? - person Nate; 20.07.2010
comment
@GarethOwen: Разве использование устаревшего не является преимуществом того, как компилятор сообщает о предупреждении / ошибке, если он присутствует в ссылочном коде? Если да, то вам не повезло с написанием собственного, боюсь: stackoverflow.com/questions/154109/custom-compiler-warnings/ Мне действительно сложно понять, что не так с пометкой устаревшего кода как устаревшего .... - person MPritchard; 20.07.2010
comment
@Nate Bross: Я думаю, вы имеете в виду устаревшие ... Устаревшие означает выраженное серьезное неодобрение устаревших означает, что они больше не используются в целом, или заменяются для этой цели чем-то более новым. Однако, что касается предупреждений компилятора, для устаревшего варианта нет, поэтому устаревшее - это все, что у нас есть, и это достаточно близко. - person NotMe; 20.07.2010
comment
У нас нет планов по замене унаследованного кода - вот почему слово «устаревшее» кажется неправильным - я просто не хочу, чтобы новый код ссылался на него напрямую. В тех немногих местах, где мне нужно сослаться на устаревший код, я буду скрывать его за (не устаревшим) интерфейсом. - person GarethOwen; 20.07.2010
comment
Кто-нибудь знает что-нибудь о FxCop? Могу ли я написать собственное правило для определения того, когда класс из пространства имен newCode ссылается на класс в пространстве имен прежних версий? - person GarethOwen; 21.07.2010

Как говорили другие, используйте устаревший атрибут (даже если вам нужно его переименовать).

Но сделайте еще один шаг. УДАЛИТЕ ЛЮБОЙ устаревший метод, который больше НЕ используется, как можно скорее. Это помешает кому-либо использовать его позже. Вы должны начать видеть предупреждения компилятора из-за того, что устаревшие атрибуты со временем теряют силу.

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

person NotMe    schedule 20.07.2010
comment
Мы добавили его как статистику сборки в нашу сборку TeamCity. Есть что-то приятное в том, что график медленно стремится к 0 - person MPritchard; 20.07.2010