Home

Source Generator Support?

Is this something that could be integrated into LINQPad?

I love the fact that LINQPad allows me to try out new features of the language/framework usually but it looks like this needs build and IDE support. This could allow for making very dynamic LINQPad scripts with specially crafted generators that I would love to play around with.

Comments

  • LINQPad could in theory be made to work with source generators. The issue - from what I've seen so far - is in the way they're packaged, which relies on MSBuild, project files and PowerShell scripts.

    If particular source generators become popular, it's likely that I could hard-code support for those generators. Is there anything that you have in mind?

  • I don't have any particular generator in mind. Just wanted to see if this could be supported in general so I could author and use generators that I'd write and eventually share.

    But I'd imagine any generators that would come with the usual core packages ought to be included (asp.net core, ef core, etc.)

  • A possible use case I might try to create a generator for, suppose we had a class that contained a list of optional (nullable) properties. We want it to implement an interface that has a subset of the same corresponding properties, but some or all of its properties are non-nullable. The generator could generate explicit implementations of the accessors, perhaps adds a validation function as well to validate all the required properties.

  • One example of a source generator that would be very useful is Refit. I've been unable to use LinqPad to test Refit-based libraries and nuget packages because it requires running sourcegen to create interface stubs. Without that, you get the somewhat unhelpful error "ISomeRefitClient doesn't look like a Refit interface. Make sure it has at least one method with a Refit HTTP method attribute and Refit is installed in the project."

    Source generator support in general would be great but support for Refit specifically would be very helpful.

  • @Nick said:
    One example of a source generator that would be very useful is Refit. I've been unable to use LinqPad to test Refit-based libraries and nuget packages because it requires running sourcegen to create interface stubs.

    With ProxyRestService from here https://gist.github.com/bennor/c73870e810f8245b2b1d you can use Refit in LINQPad. If you're on Refit 4 or newer (you probably are), you need to swap in the lines in the last comment. If you add Refit, Castle and the gist code to your MyExtensions you can then var api = ProxyRestService.For<IMyApi>(...) without issues. Or just add it to the queries you want it in.

  • I envision being able to store CSV files in a directory next to my linqpad script, and linqpad would automatically generate the DTOs and code necessary to deserialize the files. At any point in time, I could drop in a CSV, and immediately begin querying the file in linqpad.

    That sounds so awesome to me. :)

  • +1 for refit support. I use refit quite regularly to avoid HttpClient boilerplate code. Any chance to add the support, @JoeAlbahari ?

  • The workaround suggested by @rdavisau works well for me. Here's a working version as a LINQ query - save it to refit.linq. Then you can import it into any query with #load refit.
    http://share.linqpad.net/xn3ac8.linq

    It would be a lot of work to allow LINQPad to host source generators, and even then, it may be viable only for LINQPad 5 (which runs on .NET Framework, with support for AppDomains). I don't think it's practical to host source generators in .NET 6, unless you move the entire Roslyn toolchain out-of-process (a massive job with performance implications) - or are happy to risk leaking memory and destabilizing the host with ALC-based isolation.

  • Source Generator support would be a great addition to LinqPad. SG seems to be getting a lot more popular, especially as we move to AOT compilation in dotnet 8. Most things we used to do with reflection are now source generated.

    Here's one example of a great library which relies on it. https://github.com/SteveDunn/Vogen

  • Somewhat off-topic, but regarding that particular library, might it be largely redundant now with records? The following:

    [ValueObject<int>]
    readonly partial struct CustomerId
    {
        public static Validation Validate (int value) =>
            value >= 0 ? Validation.Ok : Validation.Invalid ("Must be greater >= zero.");
    }
    

    can be accomplished with the same amount of code by using a field initializer to validate a record's primary constructor parameter:

    record CustomerId (int ID)
    {
        public readonly int ID = ID < 0
            ? throw new ArgumentOutOfRangeException ("ID must be >= 0")
            : ID;
    }
    
  • @JoeAlbahari said:
    Somewhat off-topic, but regarding that particular library, might it be largely redundant now with records? The following:

    [ValueObject<int>]
    readonly partial struct CustomerId
    {
        public static Validation Validate (int value) =>
            value >= 0 ? Validation.Ok : Validation.Invalid ("Must be greater >= zero.");
    }
    

    can be accomplished with the same amount of code by using a field initializer to validate a record's primary constructor parameter:

    record CustomerId (int ID)
    {
        public readonly int ID = ID < 0
            ? throw new ArgumentOutOfRangeException ("ID must be >= 0")
            : ID;
    }
    

    The issue there is that "default(CustomerId).Dump();" will get Value set with 0.The lib avoid this.

Sign In or Register to comment.