К сожалению, из-за проблем, которые разочаровывают меня, я вынужден использовать компоненты с пространствами имен, которые я не могу изменить. Из-за того, как они их структурировали, это вызывает коллизии в сгенерированном коде позади.
Опять же, к сожалению, у меня нет доступа к коду, который определяет эти пространства имен, поэтому их нельзя изменить. Понижающее голосование это никому не поможет, особенно без причины / объяснения. Кроме того, я также попытался продемонстрировать эту проблему владельцам, объяснив, почему это очень плохой дизайн , но мне сказали по другим причинам, изменить их не вариант поэтому я вынужден искать обходной путь.
Вот упрощенный пример, иллюстрирующий проблему. Рассмотрим решение с двумя проектами, библиотекой Core и потребляющим приложением:
Элементы в «базовой» библиотеке
ModelA
(Пространство имен: SomeFeature.Core.Models
)
ModelB
(Пространство имен: SomeFeature.Core.Models
)
** Предметы в «ConsumingApp» (Ссылки «Ядро») **
MainWindow
(Пространство имен: ConsumingApp.SomeFeature
)
TestControl
(Пространство имен: SomeFeature.Controls
)
Причину столкновения можно объяснить в три этапа:
SomeFeature
является как корнем одного пространства имен, так и дочерним элементом другого
TestControl
определяется как находящийся в укорененной версии пространства имен (такой же, как библиотека), а не в MainWindow
.
- Генерация кода в итоге помещает сгенерированные переменные для этих элементов XAML в область имен
MainWindow
, что не соответствует тому, что на самом деле находится в XAML.
Теперь, если бы это были переменные, заданные вручную в не сгенерированном коде, работать с этим легко. Просто добавив префикс global::
, он «укореняет» пространство имен, которое вы вводите, тем самым устраняя всю двусмысленность.
namespace ConsumingApp.SomeFeature{
public partial class MainWindow{
// Note the 'global::' prefix
global::SomeFeature.Controls.TestControl MainTestControl { get; set; }
}
}
Вышеуказанное гарантирует, что оно всегда разрешается относительно глобального пространства имен SomeFeature
, а не вложенного пространства имен ConsumerApp.SomeFeature
. Довольно прямо вперед.
Однако, автоматически сгенерированный код из синтаксического анализатора XAML не включает этот префикс global::
, поэтому в сгенерированном коде вы действительно получите это:
namespace ConsumingApp.SomeFeature{
public partial class MainWindow{
// Note: without the 'global::' prefix, this resolves to
// 'ConsumingApp.SomeFeature.Controls.TestControl'
// which doesn't actually exist, causing the mentioned issue.
SomeFeature.Controls.TestControl MainTestControl { get; set; }
}
}
Что приводит к этой ошибке:
Ошибка CS0234 Тип или имя пространства имен «Элементы управления» не существует в пространстве имен «ConsumingApp.SomeFeature» (отсутствует ссылка на сборку?)
Как отмечено в комментариях к коду, это потому, что он не ищет этот путь к классу ...
SomeFeature.Controls.TestControl
а точнее вот этот:
ConsumingApp.SomeFeature.Controls.TestControl
который не существует, из-за ошибки.
Исправление будет заключаться в том, чтобы каким-то образом автоматически сгенерированный код выводил global::
, но я не знаю, как это сделать, или даже если это можно сделать.
Вещи, которые я пробовал:
- Спорят, чтобы они изменили свои пространства имен! (Я проиграл!)
- Явная ссылка на сборку в импорте XAML:
- Определение псевдонимов в не сгенерированном коде позади
- Поиск псевдонимов в мире XAML (не найден)
- Избегайте именования элемента и вместо этого вручную ищите элемент управления через другие свойства. (Ужасно, но это работает!)
Так что можно сделать здесь, чтобы генератор кода включил префикс 'global ::', или есть другой способ сделать это?