Простое внедрение зависимости инжектора в реализацию класса IPackage
Есть ли способ внедрить зависимости в реализацию класса SimpleInjector.Packaging.IPackage? Я использую регистрацию в декораторе, и существует перегрузка RegisterDecorator, которая позволяет добавить предикат, чтобы определить, должен ли декоратор применяться к конкретному типу сервиса.
Для проведения модульных тестов предикат должен быть настраиваемым через параметр. Я пытался внедрить службу в классе Package, но я получил исключение "У пакетов должен быть конструктор по умолчанию ".
Спасибо
2 ответа
В дополнение к ответу @Steven (с которым я согласен), вы можете создать свой собственный IServicePackage
интерфейс и передать ему класс конфигурации:
public class CompositionRootSettings {
public string Something { get; set; }
}
public interface IServicePackage
{
void RegisterServices(Container container, CompositionRootSettings settings);
}
public static void RegisterServicePackages(this Container container, CompositionRootSettings settings)
{
var packages = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where typeof(IServicePackage).IsAssignableFrom(type)
where !type.IsAbstract
select (IServicePackage)Activator.CreateInstance(type);
packages.ToList().ForEach(p => p.RegisterServices(container, settings));
}
Нельзя позволять Simple Injector вводить зависимости в пакеты. Это является преднамеренным, и логическое обоснование этого аналогично тому, почему контейнер блокируется при первом разрешении. Как описывает ссылка, Simple Injector предотвращает это, потому что это опасная практика, потому что она может привести к разного рода скрытым проблемам.
Библиотека пакетов довольно проста и в ней отсутствуют такие функции, как условная регистрация. Если это то, что вам нужно, вам придется либо свернуть собственную реализацию пакета (что на самом деле тривиально; просто посмотрите на исходный код), либо явно зарегистрировать пакеты, как показано в следующем примере:
if (shouldLoadPackage1) new MyPackage1().RegisterPackages(container);
if (shouldLoadPackage2) new MyPackage2().RegisterPackages(container);
if (shouldLoadPackage3) new MyPackage3().RegisterPackages(container);