2010-11-11 37 views
0

我得到 「System.StackOverflowException是未處理的」 公共堆棧溢出問題,Asp.net MVC

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

當我改變這個它發生:

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; 
     } 
...} 

要這樣:

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; 
     } 
...} 

我對此一無所知。我將其設置爲單元測試,隨時向此服務添加類變量時,它會崩潰。我可以將一個類變量添加到另一個服務中,或者創建一個複製它的服務減去該接口並且它可以工作。有任何想法嗎?

會話服務構建:

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; 
     } 

其他服務構建物:

私人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

「SessionService」的構造函數中發生了什麼? – 2010-11-11 01:00:59

+0

添加服務構建問題。 – scottrakes 2010-11-11 01:31:02

+0

如果您將發佈由'SessoinService'創建的所有對象的所有構造函數,我相信您會發現問題:) – 2010-11-11 01:36:37

回答

1

您正在遞歸創建一組對象。

您的代碼與test logic in production「聞起來」,因爲您隱式創建所有對象。

相反,我會鼓勵使用依賴注入或其他solutions,以便在構造函數中沒有硬依賴關係。

最壞情況,只需使用ServiceLocator模式。

最後一個選項是最簡單的方法,因爲你已經有太多的東西綁定在一起。您的代碼應該是這樣的:

public class OrganizationService : IOrganizationService 
    { 

     private IValidationDictionary _validationDictionary; 
     private IOrganizationRepository _repository; 

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

讓我們來看看依賴於IOrganizationRepository這裏。

我們不需要知道它的確切類型。所以我們不在乎。 ServiceLocator是唯一關心的身體。

通常它只是一個靜態類(記住多線程和同步!)。

它可以這樣實現(我不想指向現有的實現,因爲它只是太簡單做):

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)); 
    } 
} 

然後在您的測試設置(可能在基礎測試類)只是這樣做:

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

在生產中,你會以不同的方式實例化它。

當然,使用CastleWindsor,Microsoft Unity或其他依賴注入框架會更容易。

希望這會有所幫助。