2009-08-18 12 views
4

Mes dépôts prennent tous ISession dans le constructeur:Injecter ISession Into My Référentiels Utilisation StructureMap dans un Asp.Net MVC application

protected Repository(ISession session) 
{ 
    this.session = session; 
} 
private readonly ISession session; 

Dans une application MVC Asp.Net, en utilisant StructureMap, comment pourrais-je aller sur la configuration up ISession dans mon Registre StructureMap? Aurais-je besoin d'ajouter SessionFactory au conteneur également? Est-ce que FluentNHibernate change des choses?

Répondre

1

Vous devez enregistrer ISession en utilisant une méthode d'usine.

Une autre option (pas toujours le meilleur, mais facile à utiliser) est à:

implémentent des interfaces ISession et ISessionFactory (SessionProxy et SessionFactoryProxy).

public class SessionAggregator : ISession { 
    protected ISession session; 

    public SessionAggregator(ISessionFactory theFactory) { 
     if (theFactory == null) 
      throw new ArgumentNullException("theFactory", "theFactory is null."); 
     Initialise(theFactory); 
    } 

    protected virtual void Initialise(ISessionFactory factory) { 
     session = factory.OpenSession(); 
    } 
    // the ISession implementation - proxy calls to the underlying session 
} 

public class SessionFactoryAggregator : ISessionFactory { 
    protected static ISessionFactory factory; 
    private static locker = new object(); 
    public SessionFactoryAggregator() { 
      if (factory == null) { 
       lock(locker) { 
       if (factory == null) 
        factory = BuildFactory(); 
       } 
      } 
    } 

    // Implement the ISessionFactory and proxy calls to the factory     
} 

De cette façon, vous pouvez simplement vous inscrire ISession (mis en œuvre par SessionAggregator) et ISessionFactory (SessionFactoryAggreagator) et tout cadre DI résoudra ISession facilement.

Ceci est bon si votre DI ne supporte pas la méthode d'usine (je ne sais pas si Structure Map le fait).

J'ai ajouté cette implémentation à mon assemblée Commons, je ne devrais donc pas la réimplémenter à chaque fois.

EDIT: maintenant, d'utiliser ISession dans l'application web:

  1. Inscrivez-SessionFactoryAggregator sur la carte de structure (durée de vie peut être singleton).
  2. Enregistrez SessionAggregator dans la mappe Snstrucure et définissez sa durée de vie sur InstanceScope.Hybrid.
  3. À la fin de chaque demande, vous devez disposer de la session en appelant HttpContextBuildPolicy.DisposeAndClearAll()

Le code peut ressembler à:

// The Registry in StructureMap 
ForRequestedType<ISessionFactory>() 
     .CacheBy(InstanceScope.Singleton) 
     .TheDefaultIsConcreteType<SessionFactoryAggregator>(); 

ForRequestedType<ISession>() 
     .CacheBy(InstanceScope.Hybryd) 
     .TheDefaultIsConcreteType<SessionAggregator>(); 

// Then in EndRequest call 
HttpContextBuildPolicy.DisposeAndClearAll() 
+0

Je suis vraiment à la recherche d'un exemple StructureMap, ou en utilisant votre exemple, comment j'injecterais SessionAggregator et SessionFactoryAggregator dans le conteneur. Prenant en considération un environnement d'application Web, contexte, sessions etc. – mxmissile

+0

J'ai mis à jour la réponse pour montrer comment enregistrer cela. –

+0

C'est exactement ce que je cherchais, merci. – mxmissile

0

This question & réponses pourraient vous aider.

Une façon de procéder: dérober la gestion de session nhibernate de "S#arp Architecture". Fonctionne très bien.