Никогда не делайте классы и пространства имен с одним и тем же именем

    • Silverlight
    • C#
    • WPF
    • XAML
    • Bug
  • modified:
  • reading: 3 minutes

Был у нас team leader (дальше просто лид). Тогда нас всех еще набирали на работу в компанию, где я сейчас работаю. Тогда намечалось создание нового продукта. Тогда нас брали, чтобы мы реализовали этот продукт. Перед тем как нас брали лид сделал правильную вещь, он остановился на модульной архитектуре, выбрал Prism, создал несколько модулей на клиенте, а на сервере под них сервисы. Раздал каждому разработчику по модулю (они практически были все независимы) и ждал результата. Очень все было верно, разработчики знали друг друга плохо, мы писали потихоньку код и знакомились.

Мне тогда достался, предположим, модуль под названием ModuleTwo:

Capture0

И так получилось, что наш лид назвал сам модуль (а следовательно его основной namespace) именем ModuleTwo, а так же добавил файл ModuleTwo.cs с классом ModuleTwo, который занимался регистрацией своего модуля:

using System;
 namespace ModuleTwo
{    public class ModuleTwo : BaseLibrary.IModuleBase
    {        public void RegisterModule()
        {            throw new NotImplementedException();
        }
    }
}

Конечно, в глаза сразу бросается одинаковые имена пространства имен и класса, хочется исправить. Но, в тот момент мне нечего было предъявить. На этой базе уже была создана архитектура, модули подгружались в зависимости от того, что прописано в базе. В общем, просто так поменять имя класса не получилось бы, на этом уже многое было завязано. Потому, претензию “не нравится” я предъявить не мог, а что-то дельное придумать не смог. Я накидал представления и модели представления и получилось, примерно, следующее:

Capture1

ViewModel в DataContext я устанавливал при помощи такой конструкции:

<UserControl x:Class="ModuleTwo.Views.SampleView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:ViewModels="clr-namespace:ModuleTwo.ViewModels" >
     <UserControl.DataContext>
        <ViewModels:SampleViewModel />
    </UserControl.DataContext>
     <!-- ... -->
 </UserControl>

Реально, полгода жили с тем, что пространства имен и модули имели одно и тоже имя, никаких проблем не всплывало, пока мне не потребовалось ViewModel объекту дать имя, чтобы на него ссылаться в байдинге:

<UserControl x:Class="ModuleTwo.Views.SampleView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:ViewModels="clr-namespace:ModuleTwo.ViewModels" >
    <UserControl.DataContext>
        <ViewModels:SampleViewModel x:Name="ViewModel" />
    </UserControl.DataContext>
     <ListBox ItemsSource="{Binding Path=ItemsCollection}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Path=Name}" />
                    <Button Command="{Binding Path=SomeCommand, ElementName=ViewModel}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</UserControl>

Вот тут-то и появилась ошибка компиляции:

The type name 'ViewModels' does not exist in the type 'ModuleTwo.ModuleTwo'

Все дело в том, что класс SampleView.xaml.cs будет содержать поле:

#line 6 "..\..\..\Views\SampleView.xaml"
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
internal ModuleTwo.ViewModels.SampleViewModel ViewModel;
С которым у компилятора и будут проблемы. А так как код этого класса генерируется VS, то я даже не знаю как повлиять на эту проблему. Можно, конечно, устанавливать все через Resources и StaticResource (пример на WPF, но я столкнулся на Silverlight, там DynamicResources нет). Можно потрудиться с Binding и решить все через другие элементы. Но я все-таки решил, что это как раз и есть предлог для того (вторым предлогом было то, что поменялся лид), чтобы покончить с путаницей пространств имен и имен модулей. Поменял имена классам, пришлось, конечно, и в архитектуре, в метаданных покопаться, но проблема решена окончательно.  

Были ли случаи у вас, когда видите какую-то неправильную вещь, чувствуете, что скорее всего проблемы будут, но пока не знаете какие? А потом их встречаете?

See Also