Как сделать строго типизированную ссылку на пространство имен, не выбирая в нем произвольный тип - PullRequest
3 голосов
/ 01 июля 2010

Я работаю над проектом, в котором я использую Depency Injection. При регистрации набора интерфейсов и классов мне нужно указать пространства имен, в которых расположены эти интерфейсы и классы.

Хотя я не люблю предоставлять строковые константы, главным образом потому, что это вредит рефакторируемости. Мне не нравится брать один из интерфейсов / классов и получать его пространство имен. Например:

typeof(FoodStore.Fruits.IApple).Namespace

потому что это выглядит странно, когда все эти имена произвольных типов задерживаются (зачем выбирать IApple вместо IOrange?), Только чтобы отвлечь от реальной точки кода. Просто нет разумного правила, какой тип выбрать.

Я придумал следующее решение.

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

namespace FoodStore.Fruits
{
    /// <summary>
    ///     Serves as a type based reference to the namespace this class
    ///     is located in.
    /// </summary>
    public sealed class _NamespaceAnchor
    {
    }
}

Теперь я могу использовать:

typeof(FoodStore.Fruits._NamespaceAnchor).Namespace

Всякий раз, когда я реорганизую пространство имен, мне не нужно беспокоиться о регистрациях DI.

Хотя это решение удовлетворяет требованиям вопроса, я все еще не доволен, потому что теперь у меня есть такие уродливые пустые классы. Я не могу сделать их internal, потому что - очевидно - ссылки охватывают разные сборки.

Мой вопрос: кто-нибудь знает более элегантное решение?

Ответы [ 2 ]

3 голосов
/ 01 июля 2010

Нет, нет ничего лучше - пространство имен не являются действительно первыми понятиями класса в CLR, насколько я знаю.Да, Type позволяет задать его для пространства имен. - но пространство имен действительно для людей, а не виртуальной машины

1003 * Обратите внимание, что в отличие от Java, нет никакого контроля доступа на уровне пространства имен.Я не проверял, но я подозреваемый нет частности маркера метаданных для пространства имен. 1007 * Я не могу думать ни о чем о пространствах имен, которые будут влиять на CLR во время выполнения.Ясно, что они влияют на язык компиляторов - но опять же, это на благо людей, так что мы можем организовать типы иерархически и не указывать, что иерархии на каждом шагу .
1 голос
/ 01 июля 2010

Я бы обеспокоен тем, что пространство имен (которое на самом деле является лишь частью имени класса) имеет функциональное значение в вашем приложении. Если более поздний инженер по обслуживанию перемещает некоторые классы, они могут случайно сломать систему впрыска, не осознавая этого. Ошибка не станет очевидной до времени выполнения и может занять некоторое время, чтобы отследить.

В этом случае я бы предпочел более явный выбор, например, использование атрибутов. Вот одна из возможностей:

public class TestInterfaceAttribute : Attribute { }

public interface IMyInjectableService { }

[TestInterface]
public class TestService : IMyInjectableService { }

public class RealService : IMyInjectableService { }

Тем не менее, большинство платформ DI уже имеют некоторую форму экспортных метаданных (чтобы помочь разрешить правильную зависимость для вашего конкретного случая использования) или структурированы таким образом, что вы определяете разрешения зависимостей явно.

...