2010-11-11 123 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或其他依赖注入框架会更容易。

希望这会有所帮助。