Простой инжектор с несколькими проектами WebAPI - PullRequest
0 голосов
/ 29 октября 2018

У меня есть решение C #, которое включает в себя несколько проектов WebAPI. Один из этих проектов, назовем его Project A, уже успешно использует SimpleInjector. Я пытаюсь добавить SimpleInjector в другой из этих проектов WebAPI, проект B, но столкнулся с проблемой.

Я пытаюсь создать второй контейнер в проекте B, как я это делал в проекте A, но когда я делаю это и пытаюсь построить решение, в Project A, который создается после Project B, возникает исключение в метод container.Verify(). Он говорит мне, что интерфейс, расположенный в проекте B (IUserService), не зарегистрирован должным образом в проекте A, но проект A не использует этот интерфейс.

В проекте B на Global.asax.cs у меня есть эта конфигурация:

/* Dependency Injection */
var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();


container.Register<IUserService>(() => { return new UserService(); }, Lifestyle.Scoped);
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

container.Verify();

GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

В проекте A у меня есть эта конфигурация:

/* Dependency Injection */
var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

container.Register<ILog>(() => { return LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); }, Lifestyle.Scoped);
container.Register<IFundRepository>(() => { return new IporangaFundRepository(dbConnectorMiddle); }, Lifestyle.Scoped);
container.Register<ITradeRepository>(() => { return new IporangaTradeRepository(dbConnectorMiddle, middleReadClient); }, Lifestyle.Scoped);
container.Register<ITradeManager, TradeManager>(Lifestyle.Scoped);

container.Register<ITradeService>(() => new TradeService(container.GetInstance<ITradeManager>()),Lifestyle.Scoped);
container.Register<ISimulationService>(() => new SimulationService(container.GetInstance<ITradeService>()), Lifestyle.Scoped);
container.Register<IBookerService>(() => new BookerService(container.GetInstance<ITradeService>(), container.GetInstance<ISimulationService>()), Lifestyle.Scoped);
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

container.Verify();

GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

Сообщение об ошибке:

System.InvalidOperationException: 'Конфигурация недействительна. Не удалось создать экземпляр для типа UserController. Конструктор типа UserController содержит параметр с именем 'userService' и введите IUserService, который не зарегистрирован. Пожалуйста убедитесь IUserService зарегистрирован или измените конструктор UserController.

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

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

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

var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

// For Log4NetAdapter<T>, please see: https://stackoverflow.com/a/25113659
container.RegisterConditional(typeof(ILog),
    c => typeof(Log4NetAdapter<>).MakeGenericType(c.Consumer.ImplementationType),
    Lifestyle.Singleton,
    c => true);

container.RegisterInstance(dbConnectorMiddle);
container.RegisterInstance(middleReadClient);

container.Register<IFundRepository, IporangaFundRepository>(Lifestyle.Scoped);
container.Register<ITradeRepository, IporangaTradeRepository(Lifestyle.Scoped);
container.Register<ITradeManager, TradeManager>(Lifestyle.Scoped);

container.Register<ITradeService, TradeService>(Lifestyle.Scoped);
container.Register<ISimulationService, SimulationService>(Lifestyle.Scoped);
container.Register<IBookerService, BookerService(Lifestyle.Scoped);

container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

container.Verify();

GlobalConfiguration.Configuration.DependencyResolver =
    new SimpleInjectorWebApiDependencyResolver(container);

Это лучше, потому что:

  • Регистрация упрощена, потому что они определяют только отображение между абстракцией (например, ITradeService) и реализацией (например, TradeService), в то время как Simple Injector Auto-Wire типы разрешается путем проверки конструкторов. 'зависимости.
  • Мало того, что регистрация упрощена, теперь Simple Injector знает о структуре полного графа зависимостей и поэтому может эффективно выполнять проверку от вашего имени. Это, например, позволит Simple Injector найти любые несоответствия образа жизни .
  • Для абстракции ILog используется условная регистрация. Это позволяет Simple Injector внедрять ILog реализацию, специфичную для типа потребления. Это позволяет вашей библиотеке журналов регистрировать информацию об исходном классе. Это то, что не сработало при вашей регистрации, где всегда вводится логгер с типом, который содержит ваши регистрации.
0 голосов
/ 29 октября 2018

RegisterWebApiControllers использует отражение под крышками для поиска реализаций ApiController.

Полагаю, на основании полученной ошибки проект B ссылается на проект A, и вызов container.RegisterWebApiControllers в проекте A также находит и регистрирует контроллеры проекта B.

Теперь, когда вызывается .Verify(), он сканирует конструкторы ApiControllers в проекте B, находит зависимость от IUserService и прерывается, потому что эта регистрация фактически отсутствует в проекте A.

Пакет интеграции содержит еще одну перегрузку для RegisterWebApiControllers, которая принимает массив сборок, которые должны быть проверены на ApiControllers вместо сканирования по всем ссылочным сборкам.

При условии, что сборка проекта A содержит все ApiControllers, которые необходимо зарегистрировать, эта перегрузка может использоваться в проекте A, например:

container.RegisterWebApiControllers(GlobalConfiguration.Configuration,
         new[] {typeof(MyApiControllerInProjectA).Assembly});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...