2010-11-11 23 views
0

Je reçois "System.StackOverflowException était non gérée" sur les partenariats publicStack Overflow problème, Asp.net MVC

VolunteerDBEntities() : base("name=VolunteerDBEntities", "VolunteerDBEntities") 
     { 
      OnContextCreated(); 
     } 

Il arrive quand je change ceci:

public class OrganizationService : IOrganizationService 
    { 

     private IValidationDictionary _validationDictionary; 
     private IOrganizationRepository _repository; 

     public OrganizationService(IValidationDictionary validationDictionary) 
      : this(validationDictionary, new OrganizationRepository()) 
     { } 


     public OrganizationService(IValidationDictionary validationDictionary, IOrganizationRepository repository) 
     { 
      _validationDictionary = validationDictionary; 
      _repository = repository; 
     } 
...} 

à ceci:

public class OrganizationService : IOrganizationService 
    { 

     private IValidationDictionary _validationDictionary; 
     private IOrganizationRepository _repository; 
     private ISessionService _session; 

     public OrganizationService(IValidationDictionary validationDictionary) 
      : this(validationDictionary, new OrganizationRepository(), new SessionService()) 
     { } 


     public OrganizationService(IValidationDictionary validationDictionary, IOrganizationRepository repository, ISessionService session) 
     { 
      _validationDictionary = validationDictionary; 
      _repository = repository; 
      _session = session; 
     } 
...} 

Je ne sais rien sur celui-ci. Je l'ai mis en place pour les tests unitaires et chaque fois que j'ajoute une variable de classe à ce service, il se bloque. Je peux ajouter une variable de classe à un autre service ou créer un service qui réplique ceci moins l'interface et cela fonctionne. Des idées?

session service Construct:

public class SessionService: ISessionService 
    { 
     private IMembershipService _membershipService; 
     private IVolunteerService _volunteerService; 
     private IMessageService _messageService; 

      public SessionService() 
      : this(new AccountMembershipService(null), new VolunteerService(null), new MessageService()) 
     {} 


      public SessionService(IMembershipService membershipservice, IVolunteerService volunteerservice, IMessageService messageservice) 
     { 
      _membershipService = membershipservice; 
      _volunteerService = volunteerservice; 
      _messageService = messageservice; 
     } 

Autres services: Constructs

privé IValidationDictionary _validationDictionary; private IVolunteerRepository _repository; private IOrganizationService _orgservice;

public VolunteerService(IValidationDictionary validationDictionary) 
    : this(validationDictionary, new VolunteerRepository(), new OrganizationService(null)) 
{} 


public VolunteerService(IValidationDictionary validationDictionary, IVolunteerRepository repository, IOrganizationService orgservice) 
{ 
    _validationDictionary = validationDictionary; 
    _repository = repository; 
    _orgservice = orgservice; 

} 



public class AccountMembershipService : IMembershipService 
{ 
    private readonly System.Web.Security.MembershipProvider _provider; 
    private IValidationDictionary _validationDictionary; 
    private IVolunteerService _volservice; 
    private IEmailService _emailservice; 

    public AccountMembershipService(IValidationDictionary validationDictionary) 
     : this(validationDictionary, null, new VolunteerService(null), new EmailService()) 
    { 
    } 

    public AccountMembershipService(IValidationDictionary validationDictionary, System.Web.Security.MembershipProvider provider, VolunteerService volservice, EmailService emailservice) 
    { 
     _validationDictionary = validationDictionary; 
     _provider = provider ?? Membership.Provider; 
     _volservice = volservice; 
     _emailservice = emailservice; 
    } 
+0

Que se passe-t-il dans le constructeur de 'SessionService'? –

+0

Construction de service ajoutée à la question. – scottrakes

+0

Si vous allez poster tous les constructeurs de tous les objets créés par 'SessoinService' je crois que vous trouverez le problème :) –

Répondre

1

Vous créez l'ensemble d'objets de manière récursive.

Votre code "sent" avec test logic in production parce que vous créez tous les objets implicitement. Au lieu de cela, je voudrais encourager l'utilisation de l'injection de dépendance ou autre solutions de sorte que vous n'avez pas de dépendances dures dans vos constructeurs.

Dans le scénario dans le pire des cas, utilisez le modèle ServiceLocator.

La dernière option est la façon la plus facile de vous suivre car vous avez déjà trop de choses liées ensemble. Votre code ressemblerait à ceci:

public class OrganizationService : IOrganizationService 
    { 

     private IValidationDictionary _validationDictionary; 
     private IOrganizationRepository _repository; 

     public OrganizationService() { 
      _validationDictionary = ServiceLocator.Get<IValidationDictionary>(); 
      _repository = ServiceLocator.Get<IOrganizationRepository>(); 
     } 
    } 

Regardons la dépendance IOrganizationRepository ici.

Nous n'avons pas besoin d'en connaître le type exact. Donc on s'en fout. Le ServiceLocator est le seul corps qui s'en soucie.

Habituellement, ce n'est qu'une classe statique (gardez à l'esprit le multithreading et la synchronisation!).

Il peut être mis en œuvre comme celui-ci (je ne veux pas pointer vers des implémentations existantes, car il est tout simplement trop simple):

public static class ServiceLocator { 
    static Func<T, object> _resolver; 

    public static Setup(Func<T, object> resolver) { 
     _resolver = resolver; 
    } 

    public static TService Get<TService>() { 
     if (_resolver == null) throw InvalidOperationException("Please Setup first."); 
     return (TService)_resolver.Invoke(typeof(TService)); 
    } 
} 

Ensuite, dans votre configuration de test (probablement sur la classe de test de base) faites simplement ceci:

ServiceLocator.Setup(what => { 
    if (what == typeof(IOrganizationRepository)) 
     return organisationRepository = organisationRepository ?? new OrganizationRepository(); // Singleton 
    throw new NotSupportedException("The service cannot be resolved: " + what.Name); 
}); 

En production, vous l'instanciez différemment.

Bien sûr, cela peut être plus facile avec CastleWindsor, Microsoft Unity ou tout autre framework d'injection de dépendance.

Espérons que cela aidera.