Question

Nouveau pour Château / Windsor, s'il vous plaît ours avec moi.

Je suis actuellement en utilisant le cadre System.Web.Mvc.Extensibility et dans son code de démarrage, il a enregistré HttpContextBase comme suit:

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 fais cela, je me 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>, cependant, je reçois toujours la même erreur. Tous les conseils?

Merci à l'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érite 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 HttpContextBase objet tel que je peux obtenir le chemin du serveur d'un fichier xml.

Était-ce utile?

La solution

A ce jour, PerWebRequest style de vie 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, faisant passer explicitement le contexte actuel en tant que paramètre constructeur, par exemple:.

    container.Register(Component.For<IBootstrapperTask>()
                                .Instance(new RegisterRoutes(Context)));
    
  2. Utilisez HostingEnvironment.MapPath au lieu de contextBase.Server.MapPath. Vous voulez faire 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 ensuite IServerMapPath dans votre RegisterRoutes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top