Не имея возможности изменить их, как можно избежать столкновения пространства имен, вызванного XAML? - PullRequest
0 голосов
/ 01 сентября 2018

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

Опять же, к сожалению, у меня нет доступа к коду, который определяет эти пространства имен, поэтому их нельзя изменить. Понижающее голосование это никому не поможет, особенно без причины / объяснения. Кроме того, я также попытался продемонстрировать эту проблему владельцам, объяснив, почему это очень плохой дизайн , но мне сказали по другим причинам, изменить их не вариант поэтому я вынужден искать обходной путь.

Вот упрощенный пример, иллюстрирующий проблему. Рассмотрим решение с двумя проектами, библиотекой Core и потребляющим приложением:

Элементы в «базовой» библиотеке

  • ModelA (Пространство имен: SomeFeature.Core.Models)
  • ModelB (Пространство имен: SomeFeature.Core.Models)

** Предметы в «ConsumingApp» (Ссылки «Ядро») **

  • MainWindow (Пространство имен: ConsumingApp.SomeFeature)
  • TestControl (Пространство имен: SomeFeature.Controls)

Причину столкновения можно объяснить в три этапа:

  1. SomeFeature является как корнем одного пространства имен, так и дочерним элементом другого
  2. TestControl определяется как находящийся в укорененной версии пространства имен (такой же, как библиотека), а не в MainWindow.
  3. Генерация кода в итоге помещает сгенерированные переменные для этих элементов 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::, но я не знаю, как это сделать, или даже если это можно сделать.

Вещи, которые я пробовал:

  1. Спорят, чтобы они изменили свои пространства имен! (Я проиграл!)
  2. Явная ссылка на сборку в импорте XAML:
  3. Определение псевдонимов в не сгенерированном коде позади
  4. Поиск псевдонимов в мире XAML (не найден)
  5. Избегайте именования элемента и вместо этого вручную ищите элемент управления через другие свойства. (Ужасно, но это работает!)

Так что можно сделать здесь, чтобы генератор кода включил префикс 'global ::', или есть другой способ сделать это?

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