C#: Автоматическое удаление ненужных ссылок на сборку?
-
27-10-2019 - |
Вопрос
Я работаю с большой кодовой базой с огромным количеством проектов, каждый из которых имеет несколько (а в некоторых случаях огромное) количество ссылок на других. Со временем был проведен существенный рефакторинг на этой кодовой базе, и в результате есть много собраний, на которые ссылаются некоторые проекты только потому, что они использовали для содержания класса, который с тех пор перемещался в другом месте; Что-то в этом роде.
У Resharper есть инструмент, интегрированный в IDE, который позволяет пользователям находить код, который фактически использует заданный ссылку для данного проекта, однако, чтобы превратить это в решение, которое нам нужно, чтобы заставить человека щелкнуть правой кнопкой мыши на каждом ссылке в каждом проекте а затем фактически проверить отсутствие использования, а затем удалить их, что является не только длинным процессом, но и граничит с пытками.
Я хотел бы иметь возможность автоматизировать этот процесс, чтобы мы просто запустили его, и ненужные ссылки были удалены; Тогда мы могли бы интегрировать его в какой -то обычный процесс, чтобы быть пойманными пропущенными ошибками.
Двумя вариантами, о которых я подумал, - это а) автоматизировать повторный решар с PowerShell, если это возможно, или b), возможно, диаграммы зависимости архитектуры Visual Studio 2010 могут справиться с этим, и, возможно, в сценарии, если мне повезет.
Мои вопросы это:
- Можно ли быть сценарием для чего -то подобного?
- Предоставляет ли архитектура VS2010 для удаления неиспользованных ссылок каким -либо пакетным/автоматизированным способом?
Решение
Вы должны быть в состоянии сделать это с простой PowerShell:
1) Загрузите Visual Studio с вашим решением
2) Скомпилируйте все решение
3) Оставить против работы и стартового PowerShell.exe
4) Возьмите ссылку на все еще действующий экземпляр DTE VS от гнили (важный - убедитесь, что работает только один экземпляр - если он поднят, PowerShell тоже должна быть):
ps> $dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("visualstudio.dte")
5) Проверка путем перечисления всех проектов в решении с их ссылками:
ps> $dte.solution.projects | select @{l="name";e={$_.name}}, `
@{l="references";e={$_.object.references|select -exp name}} | ft -auto
... сбрасывает все имена и ссылки проекта ...
6) Теперь напишите немного сценария, чтобы пройти папку решений и проекты
7) Когда вы нажимаете папку Bin , загрузите сборку только с отражением только нагрузки:
$assembly = [reflection.assembly]::reflectiononlyload($dll)
8) Получите действительный Ссылки на сборку в вашей сборке вывода
$refs = $assembly.getreferencedassemblies()
9) Сравните действительный Ссылки на сборки на сборки, на которые ссылаются в проекте, и удалите избыточные через модель объекта VS DTE DTE
# example
$currentproj.object.references.item("system.core").remove()
$currentproj.save()
10) Прибыль!
Это работает, потому что .NET только ссылки на сборы, которые фактически упоминаются в коде. Извините, я не могу опубликовать полный рабочий пример, но этого должно быть достаточно, чтобы начать вас.
-Otisin
Другие советы
Не полное решение, но посмотрите на Установите зависимости CSPROJ, когда проекты также зависят от сборки из бин. а также Как найти неправильные зависимости сборки через PowerShell. Анкет Существует способ найти ссылки на другие проекты и как найти ссылки в собрании.
Вторая часть такая же, как и предложил OISIN. Первый немного отличается - он захватывает ссылки из файла CSPROJ (взятый в виде XML -файла и обрабатывается таким образом).
Принять это по крайней мере как вдохновение;)
Я следовал инструкциям @x0n, но для меня это не сработало. Может, я что -то упустил. Я должен признать, что не могу загрузить свой dll
с ReflectionOnlyLoad
Из -за ошибки COM. Итак, я загрузил их LoadFile
. Анкет Ссылки на сборку, предоставленные LoadFile
был точно таким же, когда я загрузил сборку с отражателем. В конце концов мой скрипт PowerShell сгенерировал список, показывающий ссылки, которые находятся в проекте, но не загружаются сборкой. Теоретически это предполагается «ненужные» ссылки. Когда я начал их удалять, сборка потерпела неудачу. Например, в случае моего первого проекта отсутствие каких -либо из 4 «ненужных» ссылок приведет к неудаче. Я просматриваю вывод сценария PowerShell, и он перечисляет "System
"Также, например. Если я удалю его, компилятор даже не жалуется на кучу"using System;
«Но до этого не удастся - заявив, что мне нужно ссылаться на эту сборку из -за интерфейса ... Кстати, наш проект не игрушка, он включает в себя 140+ DLL (почти половина из которых тест nUnit
DLL, хотя) и я подумал, что сделаю немного жилья. Мой скрипт (который не переходит в папки проекта - некоторые проекты содержат больше DLL), так что, возможно, кто -то может его использовать:
`
$ dte = [System.Runtime.Interopservices.marshal] :: getactiveObject ("visualstudio.dte")
$binfiles=Get-ChildItem C:\YourSourcePath\bin\debug
$dlls=$binfiles | where { $_.extension -eq ".dll" -and $_.name -like "*YourCompanyName*" }
foreach ($dll in $dlls) {
foreach($prj in $dte.solution.projects) {
if ($prj.Kind -eq "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") {
if ($prj.Properties.Item("OutputFileName").Value -eq $dll.Name) {
$loaded = [reflection.assembly]::LoadFile($dll.FullName)
$refs = $loaded.GetReferencedAssemblies()
Write "============="
Write $dll.Name
Write "-------------"
foreach($pref in $prj.Object.References) {
$found = 0
foreach($ref in $refs) {
if ($ref.Name -eq $pref.Name) {
$found = 1
break;
}
}
if ($found -eq 0) {
Write $pref.Name
}
}
}
}
}
}
`