城堡PerRequestLifestyle无法识别 [英] castle PerRequestLifestyle not recognize
问题描述
新城堡/温莎,请多多包涵。
我目前使用的框架<一个href=\"http://weblogs.asp.net/rashid/archive/2010/01/25/just-released-system-web-mvc-extensibility-beta.aspx\"相对=nofollow> System.Web.Mvc.Extensibility 并在其启动code,它注册HttpContextBase类似如下:
<$p$p><$c$c>container.Register(Component.For<HttpContextBase>().LifeStyle.Transient.UsingFactoryMethod(() = GT;新HttpContextWrapper(HttpContext.Current)));我想要做的是改变行为,改变httpContextBase的生活方式是PerWebRequest。
所以我必须改变code以下内容:
<$p$p><$c$c>container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest.UsingFactoryMethod(() = GT;新HttpContextWrapper(HttpContext.Current)));然而,当我这样做,我得到了以下错误:
System.Configuration.ConfigurationErrorsException:看起来你忘了
注册HTTP模块Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule
添加&LT;添加名称=PerRequestLifestyle
类型=Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule,Castle.MicroKernel
/&GT;'到的&lt;的HttpModules&GT;在你的web.config节
这下我做了&LT;的System.Web&GT;
和&LT; system.webServer&GT;
,但是,我我仍然得到同样的错误。任何提示?
先谢谢了。
更新
每个请求加入code座
在system.web.mvc.extensibility框架,有一个称为extendedMvcApplication从HttpApplication的继承的类,并且在Application_Start方法,它调用BootStrapper.Execute()。此方法的这个实施是以下情况:
公共无效执行()
{
布尔shouldSkip = FALSE; 的foreach(IBootstrapperTask任务ServiceLocator.GetAllInstances&LT; IBootstrapperTask方式&gt;()排序依据(任务=&GT; task.Order))
{
如果(shouldSkip)
{
shouldSkip = FALSE;
继续;
} TaskContinuation延续= task.Execute(服务定位); 如果(续== TaskContinuation.Break)
{
打破;
} shouldSkip =延续== TaskContinuation.Skip;
}
}
正如你可以看到,它遍历IBootStrapperTask的列表,并试图执行它们。恰巧,我有我的MVC应用程序注册路线一项任务:
公共类的RegisterRoutes:RegisterRoutesBase
{
私人HttpContextBase contextBase; 保护覆盖TaskContinuation ExecuteCore(IServiceLocator的ServiceLocator)
{
contextBase = serviceLocator.GetInstance&LT; HttpContextBase&GT;();
返回base.ExecuteCore(服务定位);
} 保护覆盖无效寄存器(RouteCollection路线)
{
routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);
({?(* /)的favicon.ico(/.*)?图标= @}{*}图标,新)routes.IgnoreRoute;
routes.IgnoreRoute({*} robotstxt,新{robotstxt = @(* /)的robots.txt(/.*)?}); XmlRouting.SetAppRoutes(路线,contextBase.Server.MapPath(〜/配置/ Routes.xml));
}
}
你可以看到,我需要的getInstance(解析)一httpcontextbase对象,这样我可以得到一个XML文件的服务器的路径。
在撰写本文时,PerWebRequest生活方式不支持解决的Application_Start()。
请参阅问题描述和讨论:
- http://support.castleproject.org/projects/ IOC /问题/浏览/ IOC-ISSUE-166
- 的http://groups.google.com/group/castle-project-users/browse_thread/thread/d44d96f4b548611e
对于这种特殊情况下解决方法:
-
注册
的RegisterRoutes
作为一个实例,明确地传递给它当前上下文构造方法的参数,例如:container.Register(Component.For&LT; IBootstrapperTask&GT;()
.Instance(新的RegisterRoutes(上下文))); -
使用
HostingEnvironment.MapPath
而不是contextBase.Server.MapPath
。要使它mockable?使用它通过一个简单的界面,例如:接口IServerMapPath {
字符串的MapPath(字符串virtualPath);
}
类ServerMapPath:IServerMapPath {
公共字符串的MapPath(字符串virtualPath){
返回HostingEnvironment.MapPath(virtualPath);
}
}
container.AddComponent&LT; IServerMapPath,ServerMapPath&GT;();
再注入 IServerMapPath
到的RegisterRoutes
。
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.
As of this writing, PerWebRequest lifestyle does not support resolving in Application_Start().
See issue description and discussion:
- http://support.castleproject.org/projects/IOC/issues/view/IOC-ISSUE-166
- http://groups.google.com/group/castle-project-users/browse_thread/thread/d44d96f4b548611e
Workarounds for this particular case:
Register
RegisterRoutes
as an instance, explicitly passing it the current context as constructor parameter, e.g.:container.Register(Component.For<IBootstrapperTask>() .Instance(new RegisterRoutes(Context)));
Use
HostingEnvironment.MapPath
instead ofcontextBase.Server.MapPath
. Want to make it mockable? Use it through a simple interface, e.g.:interface IServerMapPath { string MapPath(string virtualPath); } class ServerMapPath: IServerMapPath { public string MapPath(string virtualPath) { return HostingEnvironment.MapPath(virtualPath); } } container.AddComponent<IServerMapPath, ServerMapPath>();
Then inject IServerMapPath
into your RegisterRoutes
.
这篇关于城堡PerRequestLifestyle无法识别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!