Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate CodeGen Bug when building more than once #505

Open
FabioSilvaOS opened this issue May 10, 2024 · 5 comments
Open

Duplicate CodeGen Bug when building more than once #505

FabioSilvaOS opened this issue May 10, 2024 · 5 comments

Comments

@FabioSilvaOS
Copy link

FabioSilvaOS commented May 10, 2024

Describe the bug
With the attached projects (RiaBug.zip), the SERVER project builds correctly, and the CLIENT projects build correctly, and correctly creates the generated files the FIRS TIME. For C#, the 2nd time we got a warning, and from 3rd time we do not have problems. But with VB.Net, the second time we got errors and the projects does not build anymore.
You can try in Visual Studio, but to avoid IDE quirks I tested in command line. just go to desired project folder and execute dotnet build.
After the problem arises (for VB.Net), the only one way to build again is performing dotnet clean and then dotnet build. But when you build again the problem returns.

Summary:
For C#

  1. First time it builds correctly;
  2. Second time I receive a warning: warning CS2002: Source file 'C:\tmp\RiaBug\CS\CsClient\Generated_Code\CsServer.g.cs' specified multiple times
  3. Third time and on: Builds correctly;

For VB:

  1. First time it builds correctly;
  2. From second time, the project will not build anymore. I receive multiple errors regarding duplicate members:
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(53,16): error BC30269: 'Public Sub New()' has multiple definitions with identical signatures. [C:\t
mp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(65,45): error BC30269: 'Public Shared ReadOnly Property Current As WebContext' has multiple definit
ions with identical signatures. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(95,20): error BC30269: 'Public Sub New()' has multiple definitions with identical signatures. [C:\t
mp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(103,20): error BC30269: 'Public Sub New(serviceUri As Uri)' has multiple definitions with identical
 signatures. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(111,20): error BC30269: 'Public Sub New(domainClient As DomainClient)' has multiple definitions wit
h identical signatures. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(122,35): error BC30269: 'Public Overloads Function WhatTimeIsIt(callback As Action(Of InvokeOperati
on(Of Date)), userState As Object) As InvokeOperation(Of Date)' has multiple definitions with identical signatures. [C:\tmp\RiaBug\VB\VbClient\VbClient.vb
proj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(131,35): error BC30269: 'Public Overloads Function WhatTimeIsIt() As InvokeOperation(Of Date)' has
multiple definitions with identical signatures. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(141,25): error BC30269: 'Public Function WhatTimeIsItAsync([cancellationToken As CancellationToken
= Nothing]) As Task(Of InvokeResult(Of Date))' has multiple definitions with identical signatures. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(150,38): error BC30269: 'Protected Overrides Function CreateEntityContainer() As EntityContainer' h
as multiple definitions with identical signatures. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(158,26): error BC30179: interface 'IClockServiceContract' and interface 'IClockServiceContract' con
flict in class 'VbServer.RiaBug.ClockContext'. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(178,37): error BC30179: class 'ClockContextEntityContainer' and class 'ClockContextEntityContainer'
 conflict in class 'VbServer.RiaBug.ClockContext'. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(86,29): error BC31433: Method 'OnCreated' cannot be declared 'Partial' because only one method 'OnC
reated' can be marked 'Partial'. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(44,25): error BC31433: Method 'OnCreated' cannot be declared 'Partial' because only one method 'OnC
reated' can be marked 'Partial'. [C:\tmp\RiaBug\VB\VbClient\VbClient.vbproj]
C:\tmp\RiaBug\VB\VbClient\Generated_Code\VbServer.g.vb(157,10): error BC30663: Attribute 'ServiceContractAttribute' cannot be applied multiple times. [C:\
tmp\RiaBug\VB\VbClient\VbClient.vbproj]

To Reproduce
I added this repro in zip, but it is very very simple, I saw that problems in a big project, and then I created a MRE to test
RiaBug.zip

The server project file (same for vbproj and csproj):

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

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

<ItemGroup>
    <PackageReference Include="OpenRiaServices.Hosting.AspNetCore" Version="1.1.0" />
    <PackageReference Include="OpenRiaServices.Server" Version="5.4.3" />
</ItemGroup>

</Project>

The server Program.cs file:

using OpenRiaServices.Hosting.AspNetCore;
using OpenRiaServices.Server;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenRiaServices();
builder.Services.AddTransient<RiaBug.ClockService>();

var app = builder.Build();

app.MapGet("/", () => "Hello OpenRia!");

app.MapOpenRiaServices(builder =>
{
    builder.AddDomainService<RiaBug.ClockService>();
});

app.Run();

namespace RiaBug
{
    [EnableClientAccess]
    public class ClockService : DomainService
    {
            [Invoke()]
            public DateTime WhatTimeIsIt()
            {
                return DateTime.Now;
            }
    }
}

The server Program.vb file:

Imports Microsoft.AspNetCore.Builder
Imports Microsoft.Extensions.DependencyInjection
Imports OpenRiaServices.Hosting.AspNetCore
Imports OpenRiaServices.Server

Module Program
    Sub Main(args As String())

        Dim builder = WebApplication.CreateBuilder(args)

        builder.Services.AddOpenRiaServices()
        builder.Services.AddTransient(Of RiaBug.ClockService)()

        Dim app = builder.Build()

        app.MapGet("/", Function() "Hello OpenRia!")

        app.MapOpenRiaServices(Sub(b) b.AddDomainService(Of RiaBug.ClockService)())

        app.Run()
    End Sub
End Module

Namespace RiaBug

    <EnableClientAccess>
    Public Class ClockService 
        Inherits DomainService
    
            <Invoke()>
            Public Function WhatTimeIsIt() As DateTime
                Return DateTime.Now
            End Function

    End Class
End Namespace

The client just need the proj file:

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

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <RootNamespace></RootNamespace>
    <LinkedOpenRiaServerProject>..\CsServer\CsServer.csproj</LinkedOpenRiaServerProject>
    <OpenRiaGenerateApplicationContext>true</OpenRiaGenerateApplicationContext>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="OpenRiaServices.Client.CodeGen" Version="5.4.3">
	    <PrivateAssets>all</PrivateAssets>
	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="OpenRiaServices.Client.Core" Version="5.4.3" />
  </ItemGroup>

</Project>

Expected behavior
Every time the client project needs to build correctly

Nuget package and version

  • OpenRiaServices.Client.CodeGen 5.4.3
  • OpenRiaServices.Client.Core 5.4.3
  • OpenRiaServices.Hosting.AspNetCore 1.1.0
  • OpenRiaServices.Server 5.4.3"

EDIT The same happens if I use OpenRiaServices.Client instead of OpenRiaServices.Client.Core + OpenRiaServices.Client.CodeGen

@FabioSilvaOS
Copy link
Author

For the record, I'm not sure if this is a fix or a workaround, but I found if I put in client proj file:

<EnableDefaultCompileItems>false</EnableDefaultCompileItems>

this bug disappears.

@Daniel-Svensson
Copy link
Member

I had hoped that the bug bug had been resolved in #229 where the includes are configured to remove duplciates, previously I often did something similar to below in order to avoid the problem , it might work for you

From "AspNetCore.Client.CodeGen.csproj" sample project:

	<ItemGroup>
		<Compile Remove="Generated_Code\AspNetCore.Hosting.AspNetCore.g.cs" />
		<None Include="Generated_Code\AspNetCore.Hosting.AspNetCore.g.cs" />
	</ItemGroup>

Or just add disable EnableDefaultCompileItems and add <Compile Include="**/*.cs" Exclude="Generated_Code/**;obj/**;bin/**" />

If you have any suggestion of how this could be fixed in https://github.com/OpenRIAServices/OpenRiaServices/blob/main/src/OpenRiaServices.Tools/Framework/build/OpenRiaServices.Client.CodeGen.targets feel free to create a PR

@FabioSilvaOS
Copy link
Author

@Daniel-Svensson I checked output build logs, and I think maybe it could not remove duplicates because, for example, one item is pointing to
Generated_Code\CsServer.g.cs
and other is pointing to
C:\tmp\RiaBug\CS\CsClient\Generated_Code\CsServer.g.cs
same file, but one path is relative and other absolute.

I will try check for a solution, but I need to finish my deadlines first and, for now, EnableDefaultCompileItems was enough 😄.

@Daniel-Svensson
Copy link
Member

That sounds promising.
It should hopefully be solvable by converting/normalizing the paths from the openriaservices task between full and relative paths (so they match default item includes).

I think I have seen such functionality built into msbuild.

Good luck with the deadline and in the meantime, the workaround is documented here.

@Daniel-Svensson
Copy link
Member

Daniel-Svensson commented Jun 12, 2024

Note:

  • It seems the OpenRiaServices task outputs all compile items using full paths but the EnableDefaultCompileItems uses relative paths.
    Changing the paths to relative would probably solve the "duplicate" issue

It is possible to make paths from openria code generation relative either in code or using https://learn.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=vs-2022#msbuild-makerelative

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants