1

I am stuck with a stack overflow exception in this section of code, it is obviously occurring because the Customer object calls a list of CustomerBackgroundLevel objects, each one of which creates a new customer object. I am trying to find a way around the issue, any help would be appreciated..

Customer Constructor -

public CustomerVO(Customer item)
    {
        CustomerID = item.CustomerID;
        CustomerName = item.CustomerName;
        ECNNumber = item.ECNNumber;

        CustomerBackgroundLevels = item.CustomerBackgroundLevels.Select(c => new CustomerBackgroundLevelVO(c)).ToList();
    }

Customer Background Level Constructor -

        public CustomerBackgroundLevelVO(CustomerBackgroundLevel item)
    {
        CustomerBackgroundLevelID = item.CustomerBackgroundLevelID;
        CustomerID = item.CustomerID;
        BackgroundLevelID = item.BackgroundLevelID;
        StartDate = item.StartDate;
        EndDate = item.EndDate;
        Customer = new CustomerVO(item.Customer);
        BackgroundLevel = new BackgroundLevelVO(item.BackgroundLevel);
    }

Customer Get Method -

        public CustomerVO GetByID(int id)
    {
        var item = repository.AsQueryable().Where(x => x.CustomerID == id).FirstOrDefault();
        if (item == null)
            return null;

        return new CustomerVO(item);
    }
2
  • As a solution, perhaps add a constructor overload for CustomerBackgroundLevelVO that takes a CustomerVO. Then you can just directly assign it to CustomerBackgroundLevelVO.Customer rather than instantiating a new one. Your Linq call in the CustomerVO constructor would then look like: CustomerBackgroundLevels = item.CustomerBackgroundLevels.Select(c => new CustomerBackgroundLevelVO(c, this)).ToList() which will avoid the infinite loop. This only makes sense though if you A) want to reuse the same CustomerVO object, and B) don't mind passing a not fully initialized object. Commented Mar 26, 2013 at 13:13
  • Or better yet, ditch all this wiring/sub-object construction in their constructors and delegate it out to a specific Factory or Builder object to create/wire these objects for you and avoid all the nested/recursive interdependencies altogether. Commented Mar 26, 2013 at 13:14

3 Answers 3

2

Yeah, as you've stated creating new objects in a loop like that is gonna lead to nothing good.

Instead of creating all these wrapper objects in your constructors, why don't you wrap them on demand? That is, when you execute some code that needs a CustomerVO object, create the CustomerVO object within that function and then let it go out of scope when the function ends.

Sign up to request clarification or add additional context in comments.

Comments

1

You can solve your loop like this:

public CustomerVO(Customer item)
{
    CustomerID = item.CustomerID;
    CustomerName = item.CustomerName;
    ECNNumber = item.ECNNumber;

    **CustomerBackgroundLevels = item.CustomerBackgroundLevels.Select(c => new CustomerBackgroundLevelVO(c,this)).ToList();
}

**public CustomerBackgroundLevelVO(CustomerBackgroundLevel item, CustomerVO vocustomer)
{
    CustomerBackgroundLevelID = item.CustomerBackgroundLevelID;
    CustomerID = item.CustomerID;
    BackgroundLevelID = item.BackgroundLevelID;
    StartDate = item.StartDate;
    EndDate = item.EndDate;
    **Customer = vocustomer;
    BackgroundLevel = new BackgroundLevelVO(item.BackgroundLevel);
}

1 Comment

Thanks for this, works very nicely. Probably going to have to re-consider this approach now though, due to the initial load speed :(
0

Is that a copy constructor? If so, you need to create a custom constructor for copying the item rather than using it in both scenarios where you new up an object and copy it.

return new CustomerVO(item);

The above is unnecessary and the problem line is:

Customer = new CustomerVO(item.Customer);

Change the above line to this:

Customer = item.Customer;

Unless you are having reference problems, which means you need to design a new constructor.

And if the item.Customer object is not a CustomerVO object, then you will need to pass the reference of the current CustomerVO object into the constructor of the CustomerBackgroundLevelVO.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.