代码之家  ›  专栏  ›  技术社区  ›  Mark A. Donohoe

如果不能更改它们,如何避免XAML引起的名称空间冲突?

  •  0
  • Mark A. Donohoe  · 技术社区  · 7 年前

    不幸的是,由于令人沮丧的问题超出了我的控制范围,我不得不使用名称空间无法更改的组件。由于他们构建它们的方式,它会在生成的代码中引发冲突。

    同样不幸的是,我无法访问定义这些名称空间的代码,因此无法更改它们。 否决投票这对任何人都没有帮助,尤其是在没有理由/解释的情况下。此外,我还试着向业主演示这个问题,解释为什么这是一个问题 非常糟糕的设计 ,但有人告诉我,出于其他原因,改变它们很重要 别无选择 ,所以我不得不到处找工作。

    下面是一个简单的例子来说明这个问题。考虑一个具有两个项目的解决方案,一个“核心”库和一个消费应用程序:

    “核心”库中的项目

    • ModelA (名称空间: SomeFeature.Core.Models )
    • ModelB (名称空间: 一些特征。果心模型 )

    **“ConsumingApp”中的项目(参考“核心”)**

    • MainWindow (名称空间: ConsumingApp.SomeFeature )
    • TestControl (名称空间: SomeFeature.Controls )

    碰撞的原因可以通过三个步骤来解释:

    1. SomeFeature 既是一个命名空间的根,也是另一个命名空间的子命名空间
    2. 测试控制 定义为位于命名空间的根版本(与库相同),而不是 主窗口 他进来了。
    3. 代码生成最终将这些XAML元素的生成变量放在 主窗口 ,与XAML中的实际内容并不匹配。

    现在,如果这些是在非生成代码中手动定义的变量,那么处理起来就很容易了。只需添加前缀 global:: 它“根”您正在键入的名称空间,从而消除所有歧义。

    namespace ConsumingApp.SomeFeature{
    
        public partial class MainWindow{
    
            // Note the 'global::' prefix
            global::SomeFeature.Controls.TestControl MainTestControl { get; set; }
        }
    }
    

    以上内容将确保它始终相对于全球 某些特征 命名空间,而不是嵌套的 ConsumerApp.SomeFeature 名称空间。非常直截了当。

    然而,XAML解析器自动生成的代码并不包括这一点 全球的:: 前缀,所以在生成的代码中,实际上可以得到:

    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”中不存在类型或命名空间名称“Controls”。SomeFeature'(是否缺少装配参考?)

    正如代码注释中指出的,这是因为它没有寻找这个类路径。。。

    SomeFeature.Controls.TestControl
    

    而是这个:

    ConsumingApp.SomeFeature.Controls.TestControl
    

    这是不存在的错误。

    解决方法是以某种方式让自动生成的代码显式输出 全球的:: 但我不知道该怎么做,甚至不知道是否可以做到。

    我尝试过的事情:

    1. 为他们更改名称空间而争论! (我输了!)
    2. 在XAML导入中显式引用程序集:
    3. 在未生成的代码隐藏中定义别名
    4. 在XAML世界中搜索别名(未找到)
    5. 避免命名元素,而是通过其他属性手动搜索控件。 (很可怕,但这确实有效!)

    那么,这里有什么方法可以让代码生成器包含“global::”前缀,还是有其他方法可以做到这一点?

    0 回复  |  直到 7 年前
    推荐文章