Unity вводит параметр в конструктор разрешаемого свойства

#c# #dependency-injection #unity-container

#c# #зависимость-внедрение #unity-контейнер

Вопрос:

Я не могу найти способ ввести параметры в этом сценарии:

 class Top
{
    private ISome some;
    public Top()
    {
        some = CreateSome(localRuntimeVariable);
    }

    //I need to pass "some" instance as a InjectionParameter to Child constructor
    [Dependency]
    public Child Child {get;set;}
}
class Child
{
    //I need to inject ISome but it can only be constructed in Top
    public Child(ISome some, Foo foo)
    {
    }
}
public class Usage
{
    private void Top GetTop(Foo foo)
    {
        return unity.Resolve<Top>(new DependencyOverride<Foo>(foo));
        //I expect: Top.Constuctor called and 'some' is assigned;
        //          Top.Child property beeing resolved: Child.Constructor called
        //          'foo' instance to be taken from unity.Resolve<Top>(new DependencyOverride<Foo>(foo));
        //          'some' instance to be taken from Top.some, but how to tell unity to inject it?
    }
}
  

Комментарии:

1. Где находится оператор resolve? Какие ссылки известны при вызове Resolve?

2. Да, я видел эту строку. Но в каком контексте вызывается эта строка? Пожалуйста, укажите весь метод. Какие ссылки доступны при вызове resolve?

3. Не зная точно, что делают ваши классы, Top создание собственного ISome экземпляра может быть нарушением принципа единой ответственности. Я чувствую, что ISome также должен быть введен в Top. Возможно, вы можете использовать фабрику и InjectionFactory класс в Unity, чтобы как-то это сделать?

Ответ №1:

 class Top
{
    public Top( Foo foo, IUnityContainer container )
    {
        some = CreateSome(localRuntimeVariable);
        Child = container.Resolve<Child>(new ParameterOverride("some" some),
            new ParameterOverride("Foo", foo));
    }

    public Child Child {get;private set;}
}

class Child
{
    public Child(ISome some, Foo foo)
    {
    }
}
  

Теперь вы можете разрешить экземпляр top с помощью unity.Resolve<Top>(new ParameterOverride("Foo", foo))

Класс Usage не нужен. GetTop(Foo foo) это просто синтаксический сахар для unity.Resolve<Top>(new DependencyOverride<Foo>(foo))

Комментарии:

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

2. Они этого не делают. Я бы не стал задавать здесь вопрос о том, кто из моей команды знал, как это решить.

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

4. Ну, тогда я делаю вывод, что вы не можете передавать параметры свойствам, помеченным как зависимости, из класса, в котором они объявлены. И мне нужно переделать свой код.