Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net web api 具有多个WebAPI项目的简单注入器_Asp.net Web Api_Simple Injector - Fatal编程技术网

Asp.net web api 具有多个WebAPI项目的简单注入器

Asp.net web api 具有多个WebAPI项目的简单注入器,asp.net-web-api,simple-injector,Asp.net Web Api,Simple Injector,我有一个包含多个WebAPI项目的C解决方案。其中一个项目,我们称之为项目A,已经成功地使用了SimpleInjector。我试图将SimpleInjector添加到这些WebAPI项目中的另一个,即项目B,但我面临一个问题 我正试图在项目B中创建第二个容器,就像在项目a中一样,但当我这样做并尝试构建解决方案时,在项目a中(在项目B之后构建)的容器中存在异常。请验证方法。它告诉我,位于项目B IUserService的接口没有在项目a正确注册,但项目a没有使用此接口 在Global.asax.c

我有一个包含多个WebAPI项目的C解决方案。其中一个项目,我们称之为项目A,已经成功地使用了SimpleInjector。我试图将SimpleInjector添加到这些WebAPI项目中的另一个,即项目B,但我面临一个问题

我正试图在项目B中创建第二个容器,就像在项目a中一样,但当我这样做并尝试构建解决方案时,在项目a中(在项目B之后构建)的容器中存在异常。请验证方法。它告诉我,位于项目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);
/* 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);
在项目A中,我有以下配置:

/* 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);
/* 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,或更改的构造函数 用户控制器

RegisterWebApp控制器使用封面下的反射来搜索ApicController的实现

我猜,根据您得到的错误,项目B被项目A引用,对项目A中container.RegisterWebApp控制器的调用也会找到并注册项目B的控制器

现在,当调用.Verify时,它将扫描项目B中APIController的构造函数,发现对IUserService的依赖并中断,因为项目a中实际上缺少此注册

集成包包含RegisterWebApp控制器的另一个重载,该重载接受必须为ApicController扫描的程序集数组,而不是扫描所有引用的程序集

假设项目A的程序集包含所有需要注册的APIController,则此重载可在项目A中使用,如:

container.RegisterWebApp控制器GlobalConfiguration.Configuration, 新[]{typeofmyapicontrolleringprojecta.Assembly}; RegisterWebApp控制器使用封面下的反射来搜索ApicController的实现

我猜,根据您得到的错误,项目B被项目A引用,对项目A中container.RegisterWebApp控制器的调用也会找到并注册项目B的控制器

现在,当调用.Verify时,它将扫描项目B中APIController的构造函数,发现对IUserService的依赖并中断,因为项目a中实际上缺少此注册

集成包包含RegisterWebApp控制器的另一个重载,该重载接受必须为ApicController扫描的程序集数组,而不是扫描所有引用的程序集

假设项目A的程序集包含所有需要注册的APIController,则此重载可在项目A中使用,如:

container.RegisterWebApp控制器GlobalConfiguration.Configuration, 新[]{typeofmyapicontrolleringprojecta.Assembly};
以下不是对您问题的回答,而是如何改进和简化项目a的注册的建议

我建议使用以下代码连接项目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通过检查构造函数的依赖关系自动连接类型。 不仅简化了注册,而且现在Simple Injector知道完整依赖关系图的结构,因此可以有效地代表您进行验证。例如,这将允许简单的注入器找到任何。 ILog抽象使用条件注册。这允许Simple Injector注入特定于消费类型的ILog实现。这允许日志库记录有关原始类的信息。这在您的注册中是不起作用的,因为它总是向记录器注入包含您的注册的类型。
以下不是对您问题的回答,而是如何改进和简化项目a的注册的建议

我建议使用以下代码连接项目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通过检查构造函数的依赖关系自动连接类型。 注册不仅简化了,而且现在变得简单了 ctor知道完整依赖关系图的结构,因此可以有效地代表您进行验证。例如,这将允许简单的注入器找到任何。 ILog抽象使用条件注册。这允许Simple Injector注入特定于消费类型的ILog实现。这允许日志库记录有关原始类的信息。这在您的注册中是不起作用的,因为它总是向记录器注入包含您的注册的类型。
所以现在的问题是:为什么OP从项目A引用项目B?对我来说,这似乎不是一个正确的设计。最好的办法是将公共性提取到一个新的程序集中,这两个项目都引用csn。所以现在的问题是:为什么OP引用项目a中的项目B?对我来说,这似乎不是一个正确的设计。最好的办法是将通用性提取到一个新的程序集中,这两个项目都引用了csn。在查看您的配置时,我不禁注意到,您很少使用容器创建实例的能力,并且自动注入了依赖项。您应该更喜欢这种方法,因为1。这将导致更简单的代码和2。允许简单的注入器为您检测错误。嘿@Steven!很高兴在这里见到你!你能给我解释一下我是怎么做的吗?我是DI World的新手,请查看我的注册替代方法的答案。在查看您的配置时,我忍不住注意到您很少使用容器创建实例并自动注入依赖项的能力。您应该更喜欢这种方法,因为1。这将导致更简单的代码和2。允许简单的注入器为您检测错误。嘿@Steven!很高兴在这里见到你!你能给我解释一下我是怎么做的吗?我是DI世界的新手,请查看我的答案,以获得注册的替代方法。