Я могу использовать Ninject ConstructorArguments со строгим именованием?

Ну, я не знаю, является ли "строгое именование" правильным словом, но что я хочу сделать, следующие.

В настоящее время я использую ConstructorArgument как, например, это:

public class Ninja
{
    private readonly IWeapon _weapon;
    private readonly string _name;

    public Ninja(string name, IWeapon weapon)
    {
        _weapon = weapon;
        _name = name;
    }
    // ..more code..
}

public void SomeFunction()
{
    var kernel = new StandardKernel();
    kernel.Bind<IWeapon>().To<Sword>();
    var ninja = kernel.Get<Ninja>(new ConstructorArgument("name", "Lee"));
}

Теперь, если я переименую параметр "имя" (например, использование ReSharper), то ConstructorArgument не обновит, и я получу ошибку периода выполнения при создании Ниндзя. Для фиксации этого, я должен вручную найти все места, я указываю этот параметр через ConstructorArgument и обновляю его. Отрицательный результат, и я обречен перестать работать в какой-то момент даже при том, что у меня есть хорошее тестовое покрытие. Переименование должно быть дешевой операцией.

Есть ли какой-либо способ, которым я могу сделать ссылку на параметр вместо этого - таким образом, что это обновляется, когда я переименовываю параметр?

8
задан stiank81 19 April 2010 в 12:15
поделиться

2 ответа

Если вы сможете рассказать больше о том, чего вы действительно пытаетесь достичь, вы получите лучший ответ . В общем, вы вообще не хотите полагаться на передачу ConstructorArgument, если в этом можно помочь - это должен быть последний способ втиснуть значение параметра в создание компонента, которым вы не владеете и, следовательно, можете полагаться на то, что не волей-неволей переименовывается в [как] во время рефакторинга. Итак, для нормального кода, если вы можете попытаться сохранить его для интерфейсов, чтобы сделать вещи однозначными, а не полагаться на имена, которые лучше.

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

Следовательно, лучшее, что статическое отражение, вероятно, позволит вам достичь, это что-то вроде:

var ninja = ninject.Get<Ninja>( ParamNamesOf(()=>new Ninja( "dummy", "dummy" )).First() );

Типичный пример, который вы увидите, - это когда нужно извлечь имя свойства, к которому осуществляется доступ в экземпляре. Это немного отличается, так как он должен работать с выражением вызова конструктора.

Что касается поиска подходящей библиотеки, в которой уже есть только это, упражнение для искателя: D (Но я бы посоветовал найти лучший способ выразить то, что вы хотите сделать, но не использующий ConstructorArgument в предпочтении в любом случае к этому подходу.)

5
ответ дан 5 December 2019 в 18:57
поделиться

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

public class Ninja
{
    private readonly IWeapon _weapon;

    public Ninja(IWeapon weapon)
    {
        _weapon = weapon;
    }

    public string Name { get; set; }

    // ..more code..
}

public void SomeFunction()
{
    var kernel = new StandardKernel();
    kernel.Bind<IWeapon>().To<Sword>();
    var ninja = ninject.Get<Ninja>();
    ninja.Name = "Lee";
}

Надеюсь, это поможет.

4
ответ дан 5 December 2019 в 18:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: