Создание объектов с использованием Unity Resolve с дополнительными параметрами - PullRequest
12 голосов
/ 02 октября 2009

Я использую 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?

Ответы [ 4 ]

18 голосов
/ 18 октября 2009

Могу ли я передать параметры конструктора в метод Unity Resolve ()?

container.Resolve<IFoo>(new ParameterOverrides<Foo> { { "name", "bar" }, { "address", 42 } });"
9 голосов
/ 02 октября 2009

Изменить: этот ответ устарел, на мой взгляд, потому что он предполагает более старую версию 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: метод инициализации

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

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

     ..
}

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

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

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

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

4 голосов
/ 08 октября 2009

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

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

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

Фабрика может быть введена с зависимостями объекта и предоставлена ​​конструктору, если требуется, или установлена ​​другими средствами, если необязательно:

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

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

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

0 голосов
/ 02 октября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...