2009-09-25 6 views
2

J'essaie d'introduire l'injection de dépendance dans une application Web Forms existante. Le projet a été créé en tant que projet de site Web (par opposition à un projet d'application Web). J'ai vu des échantillons où vous créez votre classe mondiale dans Global.asax.cs et il ressemble à ceci:Comment câbler Castle Windsor dans un projet de site Web Web Forms

public class GlobalApplication : HttpApplication, IContainerAccessor 
{ 
    private static IWindsorContainer container; 

    public IWindsorContainer Container 
    { 
     get { return container; } 
    } 

    protected void Application_Start(object sender, EventArgs e) 
    { 
     if (container == null) 
     { 
      container = <...> 
     } 
    } 

Mais dans un projet de site Web, si vous demandez d'ajouter une classe mondiale, il ne fait qu'ajouter mondiale .asax qui contient une balise de script côté serveur:

<%@ Application Language="C#" %> 

<script runat="server"> 

void Application_Start(object sender, EventArgs e) 
{ 
    // Code that runs on application startup 

} 

Il ne semble pas être un moyen pour moi de tirer de HttpApplication (et IContainerAccessor) ici. Ou est-ce que je manque quelque chose d'évident?

Répondre

5

J'ai trouvé un moyen. Le fichier global.asax ne doit contenir:

<%@ Application Language="C#" Inherits="GlobalApp" %> 

puis dans le dossier App_Code j'ai créé GlobalApp.cs

using System; 
using System.Web; 
using Castle.Windsor; 

public class GlobalApp : HttpApplication, IContainerAccessor 
{ 
    private static IWindsorContainer _container; 
    private static IWindsorContainer Container { 
     get 
     { 
      if (_container == null) 
       throw new Exception("The container is the global application object is NULL?"); 
      return _container; 
     } 
    } 

    protected void Application_Start(object sender, EventArgs e) { 

     if (_container == null) { 
      _container = LitPortal.Ioc.ContainerBuilder.Build(); 
     } 
    } 

    IWindsorContainer IContainerAccessor.Container 
    { 
     get { 
      return Container; 
     } 
    } 
} 

Il semble important de faire _container statique. J'ai trouvé que les objets de la classe GlobalApp étaient créés plusieurs fois. La méthode Application_Start est seulement appelée la première fois. Lorsque j'avais _container en tant que champ non statique, il était nul pour la deuxième instanciation et les suivantes de la classe.

Pour faire référencer le récipient facile dans d'autres parties du code, je définissais une classe d'aide Ioc.cs

using System.Web; 
using Castle.Windsor; 

public static class Ioc 
{ 
    public static IWindsorContainer Container { 
     get { 
      IContainerAccessor containerAccessor = HttpContext.Current.ApplicationInstance as IContainerAccessor; 
      return containerAccessor.Container; 
     } 
    } 
} 

De cette façon, d'autres parties du code, en cas de besoin pour accéder au conteneur peut utiliser Ioc.Container.Resolve()

Est-ce que cela ressemble à la configuration correcte?

Questions connexes