hazzik / DelegateDecompiler

A library which is able to decompile a delegate or a method body to its lambda representation
MIT License
522 stars 62 forks source link

Stack overflow problem when methods call each other #163

Closed aradalvand closed 3 years ago

aradalvand commented 3 years ago

Hi there. Thank you for developing this elegant tool.

My scenario is fairly simple: I have 2 domain classes Book and Author, and 2 DTO classes BookDto and AuthorDto which are a subselection of those domain classes.

I have 2 extension methods for converting these domain classes into their respective DTOs:

  1. One that converts a Book into a BookDto:

    [Computed]
    public static BookDto ToBookDto(this Book book)
    {
    return new BookDto
    {
        Id = book.Id,
        Title = book.Title,
        ...
        Author = book.Author.ToAuthorDto(),
    };
    }
  2. One that converts an Author into an AuthorDto

    [Computed]
    public static AuthorDto ToAuthorDto(this Author author)
    {
    return new AuthorDto
    {
        Id = author.Id,
        Name = author.Name,
        ...
        Books = author.Books.Select(b => b.ToBookDto()).ToList()
    };
    }

Now, when I do the following or something similar:

dbContext.Books.Select(b => b.ToBookDto())

I get a stack overflow exception. And the reason why, as you might've already noticed, is because ToBookDto() calls ToAuthorDto() and ToAuthorDto() calls ToBookDto(), and so on and so forth... and this process never stops.

But of course, as you can see this scenario/requirement is not weird or uncommon. So, are there currently any ways to work around this? For example, setting a MaxDepth or something, etc.

Thanks in advance.

hazzik commented 3 years ago

@AradAral thanks for reporting. But how would you want to represent the resulting query?

aradalvand commented 3 years ago

@hazzik Nevermind, I finally ended up writing a custom expression visitor to take care of that, it calls the MethodInfo.Decompile() extension method internally and takes care of maintaining a max depth, as I thought perhaps this is a concern for DelegateDecompiler. Thanks again, this is an awesome library.