2010-04-19 8 views
5

Nouveau à Castle/Windsor, s'il vous plaît ours avec moi.château PerRequestLifestyle pas reconnaître

J'utilise actuellement le cadre System.Web.Mvc.Extensibility et dans son code de démarrage, il inscrit HttpContextBase comme les suivantes:

container.Register(Component.For<HttpContextBase>().LifeStyle.Transient.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current))); 

Ce que je voulais faire est de changer le comportement et changer le mode de vie HttpContextBase être PerWebRequest.

donc je dois changer le code à ce qui suit:

container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current))); 

Cependant, quand je le fais, je suis l'erreur suivante:

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 

que je l'ai fait sous <system.web> et <system.webServer>, mais , Je reçois toujours la même erreur. Des indices?

Merci d'avance.

Mise à jour

ajouté bloc de code par demande

Dans le cadre de system.web.mvc.extensibility, il y a une classe appelée extendedMvcApplication qui héritera de HttpApplication, et dans la méthode Application_Start, il appelle BootStrapper.Execute(). Cette mise en œuvre de cette méthode est la suivante:

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; 
     } 
    } 

Comme vous pouvez le voir, il boucle une liste de IBootStrapperTask et tente de les exécuter. Il se trouve que j'ai une tâche qui enregistrent les routes dans mon application 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")); 
    } 
} 

vous pouvez voir que je dois getInstance (résolution) un objet HttpContextBase tel que je peux obtenir le chemin du serveur d'un fichier xml .

+1

quand est-ce que vous résolvez cet objet? à quel point? –

+0

sur Application_Start(), est-ce trop tôt? – Herman

+0

@Herman: ce n'est pas supporté pour le moment. Qu'essayez-vous de résoudre dans Application_Start()? –

Répondre

7

A ce jour, le mode de vie PerWebRequest ne supporte pas la résolution dans Application_Start().

Voir la description de l'émission et la discussion:

solutions de contournement pour ce cas particulier:

  1. Inscrivez-RegisterRoutes comme une instance, en passant explicitement la cu contexte rrent en tant que paramètre de constructeur, par ex.:

    container.Register(Component.For<IBootstrapperTask>() 
              .Instance(new RegisterRoutes(Context))); 
    
  2. Utilisation HostingEnvironment.MapPath au lieu de contextBase.Server.MapPath. Voulez-vous le rendre mockable? Utilisez-le à travers une interface simple, .: par exemple

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

Injecter IServerMapPath dans votre RegisterRoutes.

+0

merci pour la mise à jour, va certainement prendre l'air. – Herman