2010-12-14 43 views
0

Cette question est plus pour confirmer mon diagnostic d'un problème que nous avons rencontré - ou pour trouver des explications alternatives.StructureMap ne semble pas être prêt pendant le constructeur HttpModule - est-ce correct?

Nous avons un HTTPModule qui intercepte chaque requête faite à notre application webforms. Son travail consiste à traduire des paramètres de chaîne de caractères spécifiques que nos partenaires d'intégration envoient.

Plus important encore, il a été câblé à StructureMap comme ceci:

public class SomeModule : IHttpModule 
{ 
    public SomeModule() 
    { 
     ObjectFactory.BuildUp(this); 
    } 

    public IDependency Dependency { get; set; } 
} 

Lors d'une précédente version il est apparu que le module n'a pas été injecté par le temps qu'il a exécuté de la demande de traitement. Cela a conduit à une (laid) chèque défensif étant ajouté comme:

public class SomeModule : IHttpModule 
{ 
    public SomeModule() 
    { 
     ObjectFactory.BuildUp(this); 
     if (SomeDependency == null) 
     { 
      // HACK: Not sure why this corrects the issue! 
      Dependency = ObjectFactory.GetInstance<ISomeDependency>(); 
     } 
    } 

    public IDependency Dependency { get; set; } 
} 

Vous remarquerez le commentaire HACK - il a résolu le problème, mais sans raison valable.

Eh bien, ce même module a été réutilisé sur un autre site - et le précédent hack ne fonctionnait plus. Après l'avoir regardé pendant un certain temps, j'ai fait le changement pour déplacer l'appel StructureMap en dehors du constructeur, et voilà, ça marche.

public class SomeModule : IHttpModule 
{ 
    public IDependency Dependency { get; set; } 

    public void IHttpModule.Init(HttpApplication context) 
    { 
     Initialize(); 
     // the rest of the code 
    } 

    private bool _initialized; 
    private void Initialize() 
    { 
     if (_initialized) 
     { 
      return; 
     } 

     ObjectFactory.BuildUp(this); 
     _initialized = true; 
    } 
} 

Alors, mon j'ai quelques questions autour de ce comportement:

  • Je soupçonne que StructureMap n'a pas été complètement initialisé/configuré lorsque le constructeur HttpModule était appelé - accord/pas d'accord, tout perspicacité?
  • Je n'ai trouvé aucun matériau de référence indiquant quand attendre que StructureMap soit initialisé et prêt à répondre aux demandes. Y a-t-il une telle documentation?

Répondre

0

Je ne m'attendrais pas à ce que le comportement soit très prévisible lorsque vous essayez de construire un type dans son constructeur. De nombreuses actions normalement considérées comme sûres ne sont pas considérées comme sûres dans un constructeur (comme l'utilisation d'une propriété virtuelle dans une classe).

Où vous avez déplacé le code à l'air beaucoup mieux et je le laisserais là. Si vous ne pouvez pas faire en sorte que le conteneur crée l'instance elle-même (et soit donc obligé de la construire), une sorte de méthode Initialize est l'endroit préféré pour effectuer l'action build.

Pour répondre à votre question à la fin de votre message: Il appartient au développeur de déterminer quand StructureMap est initialisé. Dans une application Web, cela se fait presque toujours dans Global.asax dans Application_Start(). Dans ce cas, je m'attendrais à ce que le conteneur soit prêt lorsque votre module est appelé.

+0

pouvez-vous citer des références pour des préoccupations concernant la prévisibilité des appels StructureMap dans les constructeurs? En creusant pour des réponses spécifiques, j'ai couru à travers des références où Palermo (l'un des auteurs SM) utilise 'BuildUp (this);' Dans les constructeurs – STW

+0

http://codebetter.com/jeremymiller/2009/01/16/quot-buildup-quot -existing-objects-with-structuremap/ – STW

+0

Je ne peux pas situer n'importe quel endroit où ils disent que c'est une mauvaise idée. Mais l'exemple que je donnerais est l'héritage. Si vous appelez BuildUp() dans un constructeur, et qu'il remplit correctement les dépendances, cela semble correct, mais s'il y a encore plus de constructeurs à appeler dans l'arbre d'héritage, alors cette valeur pourrait être écrasée. –