Это говорит в руководстве Единицы...
ParameterOverride может использоваться только для конструкторов.
Итак, почему параметры методов не учтены?
С наилучшими пожеланиями, Ian.
Причиной, по которой я его не упомянул, честно говоря, было время разработки и тестирования, а также тот факт, что внедрение метода используется гораздо реже, чем внедрение конструктора или свойства. В частности, наши команды тестирования и документации держались за ногти, пытаясь угнаться за тем, что я им бросал.
Нет никаких технических причин для этого. Объекты Override являются расширяемыми, поэтому вполне разумно создать свои собственные, чтобы переопределить значения параметров метода, если вам это действительно нужно.
В фреймворках DI обычно используется внедрение конструктора или инъекция свойств .
Внедрение конструктора - это когда каркас конструирует экземпляры и автоматически предоставляет экземпляры, соответствующие параметрам конструктора.
Внедрение свойств - это когда после создания экземпляра любое свойство с типом, поддерживаемым контейнером, автоматически присваивается экземпляру этого типа.
Параметры обычно не поддерживаются свойствами, поэтому PropertyOverride
имеет смысл только при внедрении конструктора.
Обновление: внедрение метода в Unity позволяет вызывать метод для экземпляра, передающего параметры в вызов метода:
container.RegisterType<DriveController>(
new InjectionMethod("InitializeMe", 42.0,
new ResolvedParameter<ILogger>("SpecialLogger")));
Класс InjectionMethod
заставляет вас указывать значения для все параметры методов. Использование ParameterOverride
не имеет большого смысла в этом случае, поскольку мы уже предоставили явные значения для использования преобразователем.
Примечание: техническая причина того, почему ParameterOverride
работает только с параметрами конструктора, заключается в том, что поддержка переопределений для методов имеет некоторые проблемные случаи.Рассмотрим следующий класс:
public class Foo
{
public Foo(IService service) { ... }
public void Initialize(IService service) { ... }
}
container.Resolve<IFoo>(new ParameterOverride("service", new Service()));
Какой параметр следует переопределить?
Если вам нужно предоставить значения параметров при разрешении, я бы предложил вместо этого использовать фабричные делегаты. Преобразование примера выше:
container.RegisterInstance<Func<int, DriveController>>(
number => {
var dc = new DriveController();
dc.InitializeMe(number, container.Resolve<ILogger>("SpecialLogger"));
return dc;
});
var factory = container.Resolve<Func<int, DriveController>>();
var dc = factory(42);
Я не пробовал это с Unity. Я предполагаю, что это сработает, по крайней мере, это показывает, что должны быть альтернативы предоставлению значений параметров во «время разрешения».