城堡 PerRequestLifestyle 无法识别
刚到城堡/温莎,请耐心等待。
我目前正在使用框架 System.Web.Mvc.Extensibility 并在其启动代码中,它注册了 HttpContextBase,如下所示:
container.Register(Component.For<HttpContextBase>().LifeStyle.Transient.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));
我想做的是更改行为并将 httpContextBase 的生活方式更改为 PerWebRequest。
所以我将代码更改为以下内容:
container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));
但是,当我这样做时,出现以下错误:
System.Configuration.ConfigurationErrorsException: Looks like you forgot to
register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule
Add '<add name="PerRequestLifestyle"
type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.MicroKernel"
/>' to the <httpModules> section on your web.config
我在
和
,但是,我仍然遇到同样的错误。有什么提示吗?
提前致谢。
更新
每个请求添加的代码块
在system.web.mvc.extensibility框架中,有一个继承自HttpApplication的类extendMvcApplication,在Application_start方法中,它调用BootStrapper.Execute()。该方法的实现如下:
public void Execute()
{
bool shouldSkip = false;
foreach (IBootstrapperTask task in ServiceLocator.GetAllInstances<IBootstrapperTask>().OrderBy(task => task.Order))
{
if (shouldSkip)
{
shouldSkip = false;
continue;
}
TaskContinuation continuation = task.Execute(ServiceLocator);
if (continuation == TaskContinuation.Break)
{
break;
}
shouldSkip = continuation == TaskContinuation.Skip;
}
}
如您所见,它循环遍历 IBootStrapperTask 列表并尝试执行它们。碰巧我有一个在我的 mvc 应用程序中注册路由的任务:
public class RegisterRoutes : RegisterRoutesBase
{
private HttpContextBase contextBase;
protected override TaskContinuation ExecuteCore(IServiceLocator serviceLocator)
{
contextBase = serviceLocator.GetInstance<HttpContextBase>();
return base.ExecuteCore(serviceLocator);
}
protected override void Register(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
routes.IgnoreRoute("{*robotstxt}", new { robotstxt = @"(.*/)?robots.txt(/.*)?" });
XmlRouting.SetAppRoutes(routes, contextBase.Server.MapPath("~/Configuration/Routes.xml"));
}
}
您可以看到我需要 getInstance(resolve) 一个 httpcontextbase 对象,以便我可以获得 xml 文件的服务器路径。
New to Castle/Windsor, please bear with me.
I am currently using the framework System.Web.Mvc.Extensibility and in its start up code, it registered HttpContextBase like the following:
container.Register(Component.For<HttpContextBase>().LifeStyle.Transient.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));
What I wanted to do is to change the behavior and change the lifestyle of httpContextBase to be PerWebRequest.
so I have change the code to the following:
container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));
However, when I do this, I got the following error:
System.Configuration.ConfigurationErrorsException: Looks like you forgot to
register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule
Add '<add name="PerRequestLifestyle"
type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.MicroKernel"
/>' to the <httpModules> section on your web.config
which I did under <system.web>
and <system.webServer>
, however, I am still getting the same error. Any hints?
Thanks in advance.
Update
added code block per request
In the system.web.mvc.extensibility framework, there is a class called extendedMvcApplication which inherit from HttpApplication, and in the Application_start method, it calls BootStrapper.Execute(). This implementation of this method is the following:
public void Execute()
{
bool shouldSkip = false;
foreach (IBootstrapperTask task in ServiceLocator.GetAllInstances<IBootstrapperTask>().OrderBy(task => task.Order))
{
if (shouldSkip)
{
shouldSkip = false;
continue;
}
TaskContinuation continuation = task.Execute(ServiceLocator);
if (continuation == TaskContinuation.Break)
{
break;
}
shouldSkip = continuation == TaskContinuation.Skip;
}
}
As you can see, it loops through a list of IBootStrapperTask and tries to execute them. It so happens that I have one task that register the routes in my mvc app:
public class RegisterRoutes : RegisterRoutesBase
{
private HttpContextBase contextBase;
protected override TaskContinuation ExecuteCore(IServiceLocator serviceLocator)
{
contextBase = serviceLocator.GetInstance<HttpContextBase>();
return base.ExecuteCore(serviceLocator);
}
protected override void Register(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
routes.IgnoreRoute("{*robotstxt}", new { robotstxt = @"(.*/)?robots.txt(/.*)?" });
XmlRouting.SetAppRoutes(routes, contextBase.Server.MapPath("~/Configuration/Routes.xml"));
}
}
you can see that I need to getInstance(resolve) a httpcontextbase object such that I can get the server path of a xml file.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
截至撰写本文时,PerWebRequest 生活方式不支持在 Application_Start() 中解析。
请参阅问题描述和讨论:
此特定情况的解决方法:
将
RegisterRoutes
注册为实例,显式地将当前上下文作为构造函数参数传递给它,例如:使用
HostingEnvironment.MapPath
而不是 <代码>contextBase.Server.MapPath。想让它变得可嘲笑吗?通过简单的界面使用它,例如:然后将
IServerMapPath
注入到您的RegisterRoutes
中。As of this writing, PerWebRequest lifestyle does not support resolving in Application_Start().
See issue description and discussion:
Workarounds for this particular case:
Register
RegisterRoutes
as an instance, explicitly passing it the current context as constructor parameter, e.g.:Use
HostingEnvironment.MapPath
instead ofcontextBase.Server.MapPath
. Want to make it mockable? Use it through a simple interface, e.g.:Then inject
IServerMapPath
into yourRegisterRoutes
.Maby 尝试将其添加到“模块”部分下,如下所示:
IIS7 & Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule 注册问题
http ://www.jasonlinham.co.uk/2009/02/castle-and-iis7.html
Maby try to add it under Modules section, like here:
IIS7 & Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule registering problems
http://www.jasonlinham.co.uk/2009/02/castle-and-iis7.html