2010-04-19 69 views
5

新來的城堡/溫莎,請忍受我。城堡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><system.webServer>下沒有,但是,我仍然遇到同樣的錯誤。任何提示?

在此先感謝。

更新

加入每個請求

在system.web.mvc.extensibility框架代碼塊,有一種叫做extendedMvc​​Application類從一個HttpApplication繼承,並在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(解析)一httpcontextbase對象,這樣我可以得到一個XML文件的服務器路徑。

+1

你什麼時候解決這個問題?在哪一點? Application_Start()上的 – 2010-04-19 20:54:11

+0

,這是否太早? – Herman 2010-04-19 21:37:46

+0

@Herman:現在不支持。你想在Application_Start()中解析什麼? – 2010-04-19 23:24:16

回答

7

在撰寫本文時,PerWebRequest生活方式不支持解決的Application_Start()。

見問題描述和討論:

變通辦法這種特殊情況:

  1. 註冊RegisterRoutes作爲一個實例,明確地傳遞給它的銅作爲構造參數的rrent上下文,例如:

    container.Register(Component.For<IBootstrapperTask>() 
              .Instance(new RegisterRoutes(Context))); 
    
  2. 使用HostingEnvironment.MapPath而不是contextBase.Server.MapPath。想讓它變得可笑嗎?使用它通過一個簡單的界面,例如:

    interface IServerMapPath { 
        string MapPath(string virtualPath); 
    } 
    
    class ServerMapPath: IServerMapPath { 
        public string MapPath(string virtualPath) { 
         return HostingEnvironment.MapPath(virtualPath); 
        } 
    } 
    
    container.AddComponent<IServerMapPath, ServerMapPath>(); 
    

然後注入IServerMapPath到您的RegisterRoutes

+0

感謝您的更新,一定會看看。 – Herman 2010-04-26 15:48:32