Подтвердить что ты не робот

Создание объектов с использованием Unity Resolve с дополнительными параметрами

Я использую Prism, который также является хорошим контейнером Unity IoC. Я новичок в этой концепции, поэтому я еще не обнял ее. Теперь я хочу создать объект с помощью контейнера IoC, но также передать дополнительный параметр. Позвольте мне объяснить на примере..:

У меня есть класс, который принимает объект команд. Это зарегистрировано в контейнере IoC, поэтому он будет обрабатывать его красиво:

public class Person 
{
    public Person(IApplicationCommands commands) { .. }
    ..
}

Person person = _container.Resolve<Person>();

Теперь - я хочу передать другой аргумент - например. имя человека. Тем не менее, я все еще хочу использовать контейнер IoC для обработки разрешающей способности и, следовательно, получить другие параадресы из контейнера IoC. Но передайте имя как "пользовательский" параметр. Это можно сделать?

public class Person 
{
    public Person(IApplicationCommands commands, string name) { .. }
    ..
}

string name = "John"; 
Person person = _container.Resolve<Person>(name); // ....?? 

Этот пример, похоже, не работает, но есть ли способ заставить его работать? Или контейнер Unity IoC требует, чтобы все параметры регистрировались в контейнере до вызова Resolve?

4b9b3361

Ответ 1

Изменить: этот ответ устарел, на мой взгляд, потому что он имеет предположение о более старой версии Unity. Ответ NotDan лучше.


У вас есть несколько вариантов. Они честно немного хромают, но они будут работать.

Вариант 1: Контейнер с областью

Если вы хотите использовать конструктор инъекции, вам необходимо создать и скопируйте ваши данные в этот контейнер с областью:

IUnityContainer subContainer = _container.CreateChildContainer();

//Don't do this... create a custom type other than string, like
// MyConstructorParams or something like that... this gets the point across.
subContainer.RegisterInstance<string>("John");
Person person = subContainer.Resolve<Person>();

Вариант 2: Инициализировать метод

То, что я обычно делаю, однако, имеет отдельный метод инициализации на моем целевые объекты для переменных экземпляра:

public class Person
{
     public Person(IApplicationCommands commands)
     { .. }
     public void Initialize(string name) { .. }

     ..
}

И тогда ваше использование будет:

Person person = container.Resolve<Person>();
person.Initialize("John");

Ничего особенного, но он выполнит свою работу. Важно выбрать конвенцию и придерживаться ее, иначе вы немного потеряете.

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

Ответ 3

Есть несколько вариантов, которые вы могли бы рассмотреть:

В случае, когда вам нужно создать новый объект с законными зависимостями в дополнение к любым предоставленным данным (например, имя клиента), инкапсулируйте его в factory, который сам был введен в вызывающий объект:

Person person = _personFactory.CreatePerson("bubba");

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

var person = new Person("bubba", _domainService);

Для зависимостей переходных переменных, таких как стратегия, используемая конкретным методом, используйте Double Dispatch:

public class Person
{
    public void DoSomethingWith(SomeStrategy strategy)
    {
        strategy.DoSomething(this);
    }
 }

Ответ 4

Я не могу придумать никакого способа сделать это с помощью инъекции конструктора. Я думаю, вам нужно будет использовать вложение свойств для зависимостей (помеченных атрибутом Dependency), а затем либо взять только строку в конструкторе, создайте экземпляр самостоятельно, затем используйте BuildUp для подключения зависимостей или сделайте строку тоже свойством, которое вы установите вручную после Resolve.