我有一个包含多个WebAPI项目的C#解决方案。这些项目之一(称为项目A)已经成功使用了SimpleInjector。我正在尝试将SimpleInjector添加到这些WebAPI项目B中的另一个项目,但是我遇到了问题。
我正在尝试像在项目A中一样在项目B中创建第二个容器,但是当我这样做并尝试构建解决方案时,在项目B之后构建的项目A中有例外。 container.Verify()
方法。它告诉我位于项目B(IUserService
)上的接口未在项目A上正确注册,但是项目A没有使用此接口。
在Global.asax.cs的项目B中,我具有以下配置:
/* 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。'
答案 0 :(得分:4)
以下内容不是您问题的答案,而是有关如何改善和简化A项目注册的建议。
我建议使用以下代码代替Project A的Container
实例,而不是使用发布的代码:
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 通过检查构造函数的依赖关系来确定类型。ILog
抽象。这允许Simple Injector注入特定于消费类型的ILog
实现。这使您的日志记录库可以记录有关原始类的信息。这在您的注册中不起作用,它总是会注入一种包含您的注册的记录器。答案 1 :(得分:3)
RegisterWebApiControllers
在幕后使用反射来搜索ApiController
的实现。
我猜,基于您得到的错误,项目B引用了项目B,并且对项目A中的container.RegisterWebApiControllers
的调用也找到并注册了项目B的控制器。
现在,当调用.Verify()
时,它将扫描项目B中ApiControllers
的构造函数,找到对IUserService
的依赖关系并中断,因为该注册实际上在项目A中丢失了。 / p>
集成软件包还包含RegisterWebApiControllers
的另一个重载,该重载采用必须扫描ApiControllers
的程序集数组,而不是扫描所有引用的程序集。
假设项目A的程序集包含所有需要注册的ApiControllers
,则此重载可以在项目A中使用,例如:
container.RegisterWebApiControllers(GlobalConfiguration.Configuration,
new[] {typeof(MyApiControllerInProjectA).Assembly});