堆栈溢出问题,Asp.net MVC

发布于 2024-10-02 07:55:30 字数 3825 浏览 4 评论 0原文

我在公共场合收到“System.StackOverflowException 未处理”

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

其他服务构造:

private IValidationDictionary _validationDictionary; 私人 IVolunteerRepository _repository; 私有 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;
    }

I am getting "System.StackOverflowException was unhandled" on public

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

It happens when I change this:

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

To this:

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

I'm clueless on this one. I set this up for unit testing and anytime I add a class variable to this service, it crashes. I can add a class variable to another services or create a service that replicates this minus the interface and it works. Any ideas?

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

Other Service Constructs:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清风挽心 2024-10-09 07:55:30

您正在递归地创建对象集。

您的代码“闻起来”带有生产中的测试逻辑,因为您隐式创建了所有对象。

相反,我鼓励使用依赖注入或其他解决方案,这样你就不会在你的构造函数。

最坏情况中,只需使用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 或其他依赖注入框架会更容易。

希望这会有所帮助。

You are creating the set of objects recursively.

Your code "smells" with test logic in production because you create all the objects implicitly.

Instead I would encourage to use dependency injection or other solutions so that you do not have hard dependencies in your constructors.

In the worst-case scenario, just use ServiceLocator pattern.

The last option is the easiest way to go for you as you already have too much stuff bound together. Your code would look like this:

   public class OrganizationService : IOrganizationService
    {

        private IValidationDictionary _validationDictionary;
        private IOrganizationRepository _repository;

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

Let's look at the dependency on IOrganizationRepository here.

We don't need to know exact type of it. So we don't care. The ServiceLocator is the only body that does care.

Usually it is just a static class (keep in mind multi-threading and synchronization though!).

It can be implemented like this (I don't want to point to existing implementations because it is just too simple to do):

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

Then in your test setup (probably on the base test class) just do this:

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

In production you would instantiate it differently.

Of course it can be easier with CastleWindsor, Microsoft Unity or other dependency injection framework.

Hope that will help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文