导致错误“看起来像您忘记注册http模块Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule”的原因?
作者:互联网
我使用Castle.windsor和owin在webapi2中进行了一些DI工作.这是相关代码:
[assembly: OwinStartup(typeof(Bla.Startup))]
namespace Bla
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
//...
var container = new WindsorContainer().Install(new ControllerInstaller());
var httpDependencyResolver = new WindsorHttpDependencyResolver(container);
config.DependencyResolver = httpDependencyResolver;
//...
}
}
public class ControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly()
.Pick().If(t => t.Name.EndsWith("Controller"))
.Configure(configurer => configurer.Named(configurer.Implementation.Name))
.LifestylePerWebRequest());
//...
}
}
internal class WindsorDependencyScope : IDependencyScope
{
private readonly IWindsorContainer _container;
private readonly IDisposable _scope;
public WindsorDependencyScope(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
_scope = container.BeginScope();
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t)
? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t)
.Cast<object>().ToArray();
}
public void Dispose()
{
_scope.Dispose();
}
}
internal sealed class WindsorHttpDependencyResolver : IDependencyResolver
{
private readonly IWindsorContainer _container;
public WindsorHttpDependencyResolver(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t)
? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t)
.Cast<object>().ToArray();
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
public void Dispose()
{
}
}
owin的一大优点是它删除了system.web的依赖项.这允许从其他方面实施相当有效的(在内存中?)集成测试.我面临的问题是该行:
config.DependencyResolver = httpDependencyResolver;
引入系统依赖.因此,当我尝试运行像这样的简单测试时:
private TestServer _server;
[TestFixtureSetUp]
public void FixtureInit()
{
_server = TestServer.Create<Startup>();
}
[Test]
public voidSomeTest()
{
using (var server = TestServer.Create<Startup>())
{
HttpResponseMessage response = server.HttpClient.GetAsync("/api/bladibla/test").Result;
// ...
}
}
我得到:
{"Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule\r\nTo fix this add\r\n<add name=\"PerRequestLifestyle\" type=\"Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor\" />\r\nto the <httpModules> section on your web.config.\...
我可以在测试项目的app.config中注册什么吗?任何反馈将非常欢迎.
PS:
我尝试添加:
<system.web>
<httpModules>
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
</httpModules>
</system.web>
<system.webServer>
<modules>
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
</modules>
</system.webServer>
到app.config失败.
PPS:
好的,如果我更改:
container.Register(AllTypes.FromThisAssembly()
.Pick().If(t => t.Name.EndsWith("Controller"))
.Configure(configurer => configurer.Named(configurer.Implementation.Name))
.LifestylePerWebRequest());
至:
container.Register(AllTypes.FromThisAssembly()
.Pick().If(t => t.Name.EndsWith("Controller"))
.Configure(configurer => configurer.Named(configurer.Implementation.Name))
.LifestyleTransient());
它有效,这很有意义.最大的问题是,如何根据部署环境/测试环境或测试环境来动态更改此设置.
解决方法:
{“Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule\r\nTo fix this add\r\n\r\nto the section on your web.config….
但是您尝试注册:
PerRequestLifestyle
看到不同? PerWebRequestLifestyle不是PerRequestLifeStyle.
看一下Mauricio Scheffer`s HybridLifeStyles,它使测试容器的设置非常简单.
标签:owin,asp-net-web-api,asp-net-web-api2,castle-windsor,c 来源: https://codeday.me/bug/20191029/1958330.html