Git Product home page Git Product logo

Comments (8)

guillaumeserale avatar guillaumeserale commented on July 2, 2024 1

FYI: There's an open issue in Roslyn about the sequence order of Source Generators.

from refitter.

guillaumeserale avatar guillaumeserale commented on July 2, 2024 1

@christianhelle I've played a bit with your latest change.
If I understand correctly, the classes are generated by Refitter.SourceGenerator during the build process into the Generated Folder.
Then, Refit.Generator.InterfaceStubGeneratorV2 picks them up to generate its code.

Pretty clever 👍

I really wished the Roslyn team would have added some execution priority mechanism in the SourceGenerator.
Until then, what you implemented is the next best thing.

from refitter.

christianhelle avatar christianhelle commented on July 2, 2024

Thanks for reporting @guillaumeserale

the source generator has so far been an experiment that I started playing around with lately

I cloned your example repo and updated the .csproj to this:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
    <CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Refit.HttpClientFactory" Version="7.0.0" />
    <PackageReference Include="Refitter.SourceGenerator" Version="0.7.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

  <Target Name="ExcludeSourceGeneratedFiles" BeforeTargets="CoreCompile">
    <ItemGroup>
      <Compile Remove="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />
    </ItemGroup>
  </Target>

  <Target Name="IncludeSourceGeneratedFiles" AfterTargets="CoreCompile">
    <ItemGroup>
      <Compile Include="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />
    </ItemGroup>
  </Target>

</Project>

Which placed the generated files within the project and excludes the files right before compilation to avoid duplicate types. It looks like this in Visual Studio

image

So the problem here is that I have honestly only really tested that the project output code builds, I don't think I have actually ran any project using the source generated code yet.

You're absolutely right, it doesn't work to run the code at all! I just get this error

System.InvalidOperationException: IMyApiClient 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.
   at Refit.RestService.GetGeneratedType(Type refitInterfaceType) in /_/Refit/RestService.cs:line 169
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Refit.RestService.For(Type refitInterfaceType, HttpClient client, IRequestBuilder builder) in /_/Refit/RestService.cs:line 76
   at Refit.RestService.For[T](HttpClient client, IRequestBuilder`1 builder) in /_/Refit/RestService.cs:line 20
   at Refit.HttpClientFactoryExtensions.<>c__2`1.<AddRefitClient>b__2_3(HttpClient client, IServiceProvider serviceProvider) in /_/Refit.HttpClientFactory/HttpClientFactoryExtensions.cs:line 63
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at lambda_method1(Closure, Object, HttpContext)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)

No idea how to fix this yet, or if its even possible to fix it, since I'm not sure how to chain these source generators or how to ensure that Refitter generates code before Refit generate codes

This is definitely an interesting problem! I should probably deprecate the source generator NuGet for now and mark it as invisible

from refitter.

christianhelle avatar christianhelle commented on July 2, 2024

@guillaumeserale I found a dirty workaround...

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
    <CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Refit.HttpClientFactory" Version="7.0.0" />
    <PackageReference Include="Refitter.SourceGenerator" Version="0.7.2" />
  </ItemGroup>

  <Target Name="ExcludeSourceGeneratedFiles" BeforeTargets="CoreCompile">
    <ItemGroup>
      <Compile Remove="$(CompilerGeneratedFilesOutputPath)/**/Refitter.SourceGenerators.RefitterSourceGenerator/*.cs" />
    </ItemGroup>
  </Target>

  <Target Name="IncludeSourceGeneratedFiles" AfterTargets="CoreCompile">
    <ItemGroup>
      <Compile Include="$(CompilerGeneratedFilesOutputPath)/**/Refitter.SourceGenerators.RefitterSourceGenerator/*.cs" />
    </ItemGroup>
  </Target>

</Project>

This will keep the Refit generated code and only exclude the Refitter generated code during compilation

image

from refitter.

christianhelle avatar christianhelle commented on July 2, 2024

I deprecated all versions of the source generator in nuget.org and marked them to have critical issues

image

image

thanks again for bringing this up @guillaumeserale

I hope there's a solution to this

from refitter.

guillaumeserale avatar guillaumeserale commented on July 2, 2024

@christianhelle Thanks for the detailed explanation and analysis.
I wish I could help with a potential solution, but unfortunately, I am not well-versed in Roslyn's Source Generators 😕.

from refitter.

christianhelle avatar christianhelle commented on July 2, 2024

What do you think of this experience @guillaumeserale ?

Recording 2023-08-10 at 21 34 37

Recording 2023-08-10 at 21 50 25

The down side with this current source generator implementation is that you are required to commit the generated code to source control. On the hand, if you use the CLI Tool to generate code, then you are committing generated code to source control anyway

from refitter.

christianhelle avatar christianhelle commented on July 2, 2024

@guillaumeserale Yes, that was the best I could do for now 😅

from refitter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.