城堡PerRequestLifestyle无法识别 [英] castle PerRequestLifestyle not recognize

查看:264
本文介绍了城堡PerRequestLifestyle无法识别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新城堡/温莎,请多多包涵。

我目前使用的框架<一个href=\"http://weblogs.asp.net/rashid/archive/2010/01/25/just-released-system-web-mvc-extensibility-beta.aspx\"相对=nofollow> System.Web.Mvc.Extensibility 并在其启动code,它注册Htt​​pContextBase类似如下:

<$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框架,有一个称为extendedMvc​​Application从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()。

请参阅问题描述和讨论:

对于这种特殊情况下解决方法:


  1. 注册的RegisterRoutes 作为一个实例,明确地传递给它当前上下文构造方法的参数,例如:

      container.Register(Component.For&LT; IBootstrapperTask&GT;()
                                .Instance(新的RegisterRoutes(上下文)));


  2. 使用 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:

Workarounds for this particular case:

  1. 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)));
    

  2. Use HostingEnvironment.MapPath instead of contextBase.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆