Как заставить InternalsVisibleTo работать, когда процесс сборки подписывает сборку строгими именами? - PullRequest
6 голосов
/ 25 июня 2011

В нашем магазине мы используем Cruise Control и MSBuild для автоматизации сборок продукта в рамках непрерывной интеграции.

Часть сборки должна подписывать сборки, чтобы они имели строгие имена.

В наших файлах проекта, когда мы разрабатываем локально, в нем не указывается подпись, так как это отменяется сценарием MSBuild.

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

Это означает, что на моем компьютере я могу обновить AssemblyInfo.cs, чтобы использовать следующее выражение:

[assembly: InternalsVisibleTo("MyProject.Tests.UnitTests")]

и все хорошо.

Однако проверка этого приводит к нарушению сборки, поскольку сборочная машина подписывает сборки, эту строку необходимо обновить, чтобы она выглядела следующим образом:

[assembly: InternalsVisibleTo("MyProject.Tests.UnitTests, 
             PublicKey="magic key here..)"]

У меня есть полумрака, чтобы не подписывать собрания и не называть это днем. Тем не менее, «подписание сборок - это лучшая практика» (повторите эту мантру 3 раза), и если мы получим какую-либо выгоду от этого, я не хочу ее удалять.

Мы не устанавливаем в GAC, нас не особо беспокоит фальсификация, нам не нужно беспокоиться о третьих лицах, которые используют наши библиотеки, мы обновляем все наши файлы сразу, когда обновляем приложение. Наиболее заметным преимуществом является то, что кто-то из техподдержки не может скопировать случайную версию сборки в папку времени выполнения, и некоторые вещи могут работать некоторое время.

Я не хочу открывать банку с работами, изменяя около 100 файлов проекта вручную, чтобы включить подпись. Я также не хочу взламывать вещи, помечая вещи, которые должны быть внутренними, как публичные, я не хочу связываться с перенаправлениями и не хочу удалять модульные тесты.

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

В этом посте хорошо описана проблема и решение, но я не слишком разбираюсь в сценариях MSBuild, чтобы воспользоваться ею:

http://social.msdn.microsoft.com/forums/en-US/msbuild/thread/02df643c-956a-48bd-ac01-4a1016d91032/

Как правильно решить эту проблему?

Любые комментарии и вопросы приветствуются.

Ответы [ 2 ]

5 голосов
/ 25 июня 2011

Используйте ту же конструкцию, которую вы используете, чтобы отключить подпись сборки разработчика для определения символа компилятора, например.DO_NOT_SIGN, тогда в вашем AssemblyInfo.cs используйте это:

#if DO_NOT_SIGN
[assembly: InternalsVisibleTo("MyProject.Tests.UnitTests")]
#else
[assembly: InternalsVisibleTo("MyProject.Tests.UnitTests, PublicKey="magic key here..)"]
#endif

По моему личному мнению, это более элегантно, чем изменение исходного кода из сценария сборки.

4 голосов
/ 25 июня 2011

Вы можете добавить информацию о ключе в исходные файлы перед компиляцией.

В следующем примере используется FileUpdate из MSBuild Community Tasks и (очень грубое) регулярное выражение для исправленияключевую информацию в файлы C # AssemblyInfo.cs.

<ItemGroup>
    <AssemblyInfoFiles Include="$(MSBuildProjectDirectory)**/AssemblyInfo.cs"/>
</ItemGroup>
<FileUpdate
  Files="@(AssemblyInfoFiles)"
  Regex='(\[assembly:\s*InternalsVisibleTo\(\"[\w.]*\")(\)\])'
  ReplacementText='$1, PublicKey="$(StrongNamingPublicKey)"$2' />

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

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