Простой инжектор: регистрация типа с аргументом конструктора, основанного на его родительском
В настоящее время я пытаюсь удалить Ninject из моего проекта и перейти к использованию Simple Injector, но есть одна вещь, из-за которой я не могу нормально работать.
Для моего ведения журнала при регистрации служб я ранее мог передать параметр в свой класс ведения журнала как таковой
_kernel.Bind<ILogger>().To<Logger>()
.WithConstructorArgument("name",
x => x.Request.ParentContext.Request.Service.FullName);
Я ищу способ воссоздать это в Simple Injector. Пока у меня все работает, но это все. Я могу заставить журнал работать, хотя и не отображают правильные имена журналов, делая следующее:
_container.Register<ILogger>(() => new Logger("test"));
Кто-нибудь получил какой-либо опыт в чем-то подобном?
Ответы
Ответ 1
Эта регистрация - это форма контекстной инъекции. Вы можете использовать одну из перегрузок RegisterConditional
для этого.
RegisterConditional
однако не позволяет использовать методы factory для построения типа. Поэтому вы должны создать общую версию своего класса Logger
следующим образом:
public class Logger<T> : Logger
{
public Logger() : base(typeof(T).FullName) { }
}
Вы можете зарегистрировать его следующим образом:
container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Transient,
c => true);
Но, пожалуйста, прочитайте fooobar.com/questions/57584/... (и мой ответ) и задайте себе вопрос, если вы не слишком много регистрируетесь.
Ответ 2
Нажатие на основе контекста теперь поддерживается в Simple Injector 3 с помощью метода RegisterConditional
. Например, чтобы ввести Logger в Consumer1 и Logger в Consumer2, используйте регистр RegisterConditional, который принимает делегат типа factory следующим образом:
container.RegisterConditional(
typeof(ILogger),
c => typeof(Logger<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Transient,
c => true);