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

ConfigurationBinder source generator encounters namespace conflicts in using statements #93498

Closed
ericstj opened this issue Oct 14, 2023 · 5 comments · Fixed by #94267
Closed
Assignees
Labels
area-Extensions-Configuration source-generator Indicates an issue with a source generator feature
Milestone

Comments

@ericstj
Copy link
Member

ericstj commented Oct 14, 2023

Description

When the first part of a namespace of a bound type exists under the Microsoft namespace an error will occur

using Microsoft.Extensions.Configuration;
var c = new ConfigurationBuilder().Build();
c.Get<Foo.Bar.BType>();

namespace Microsoft.Foo
{
    internal class AType {}
}

namespace Foo.Bar
{
    internal class BType {}
}

C:\scratch\namespaceConflict\Microsoft.Extensions.Configuration.Binder.SourceGeneration\Microsoft.Extensions.Configuration.Binder.SourceGeneration.ConfigurationBindingGenerator\BindingExtensions.g.cs(22,15): error CS0234: The type or namespace name 'Bar' does not exist in the namespace 'Microsoft.Foo' (are you missing an assembly reference?) [C:\scratch\namespaceConflict\namespaceConflict.csproj]

This is happening because the generator places using statements in a namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration and this will cause the compiler to first search in containing namespaces at every level before considering the global namespace for usings placed in that namespace.

Hit this when porting eShopOnContainers.

Reproduction Steps

Build
namespaceConflict.zip

Expected behavior

Builds without issue

Actual behavior

Compilation error.

Regression?

No

Known Workarounds

Alias the reference that has the conflicting namespace, change namespace names, etc.

Configuration

No response

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Oct 14, 2023
@ghost
Copy link

ghost commented Oct 14, 2023

Tagging subscribers to this area: @dotnet/area-extensions-configuration
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

When the first part of a namespace of a bound type exists under the Microsoft namespace an error will occur

using Microsoft.Extensions.Configuration;
var c = new ConfigurationBuilder().Build();
c.Get<Foo.Bar.BType>();

namespace Microsoft.Foo
{
    internal class AType {}
}

namespace Foo.Bar
{
    internal class BType {}
}

C:\scratch\namespaceConflict\Microsoft.Extensions.Configuration.Binder.SourceGeneration\Microsoft.Extensions.Configuration.Binder.SourceGeneration.ConfigurationBindingGenerator\BindingExtensions.g.cs(22,15): error CS0234: The type or namespace name 'Bar' does not exist in the namespace 'Microsoft.Foo' (are you missing an assembly reference?) [C:\scratch\namespaceConflict\namespaceConflict.csproj]

This is happening because the generator places using statements in a namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration and this will cause the compiler to first search in containing namespaces at every level before considering the global namespace for usings placed in that namespace.

Hit this when porting eShopOnContainers.

Reproduction Steps

Build
namespaceConflict.zip

Expected behavior

Builds without issue

Actual behavior

Compilation error.

Regression?

No

Known Workarounds

Alias the reference that has the conflicting namespace, change namespace names, etc.

Configuration

No response

Other information

No response

Author: ericstj
Assignees: -
Labels:

untriaged, area-Extensions-Configuration

Milestone: -

ericstj added a commit to ericstj/eShopOnContainers that referenced this issue Oct 14, 2023
@tarekgh tarekgh added this to the 9.0.0 milestone Oct 14, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Oct 14, 2023
@tarekgh tarekgh added untriaged New issue has not been triaged by the area owner source-generator Indicates an issue with a source generator feature labels Oct 14, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Oct 14, 2023
@eerhardt
Copy link
Member

I'm hitting this same issue trying to use the ConfigBinder Source Generator with the Azure SDK:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
    <NoWarn>$(NoWarn);SYSLIB1100;SYSLIB1101</NoWarn>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0-rtm.23511.16" />
    <PackageReference Include="Azure.Data.Tables" Version="12.8.1" />
  </ItemGroup>

</Project>
using Azure.Data.Tables;
using Microsoft.Extensions.Configuration;

Console.WriteLine("Hello, World!");

static void BindToConfiguration(TableClientOptions options, IConfiguration configuration)
{
    var configurationOptionsSection = configuration.GetSection("ConfigurationOptions");
    configurationOptionsSection.Bind(options);
}

results in:

1>C:\Users\eerhardt\source\repos\ConsoleApp101\ConsoleApp101\Microsoft.Extensions.Configuration.Binder.SourceGeneration\Microsoft.Extensions.Configuration.Binder.SourceGeneration.ConfigurationBindingGenerator\BindingExtensions.g.cs(22,17,22,21): error CS0234: The type or namespace name 'Core' does not exist in the namespace 'Microsoft.Extensions.Azure' (are you missing an assembly reference?)
1>C:\Users\eerhardt\source\repos\ConsoleApp101\ConsoleApp101\Microsoft.Extensions.Configuration.Binder.SourceGeneration\Microsoft.Extensions.Configuration.Binder.SourceGeneration.ConfigurationBindingGenerator\BindingExtensions.g.cs(23,17,23,21): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'Microsoft.Extensions.Azure' (are you missing an assembly reference?)
1>C:\Users\eerhardt\source\repos\ConsoleApp101\ConsoleApp101\Microsoft.Extensions.Configuration.Binder.SourceGeneration\Microsoft.Extensions.Configuration.Binder.SourceGeneration.ConfigurationBindingGenerator\BindingExtensions.g.cs(71,71,71,89): error CS0246: The type or namespace name 'DiagnosticsOptions' could not be found (are you missing a using directive or an assembly reference?)
1>C:\Users\eerhardt\source\repos\ConsoleApp101\ConsoleApp101\Microsoft.Extensions.Configuration.Binder.SourceGeneration\Microsoft.Extensions.Configuration.Binder.SourceGeneration.ConfigurationBindingGenerator\BindingExtensions.g.cs(145,71,145,83): error CS0246: The type or namespace name 'RetryOptions' could not be found (are you missing a using directive or an assembly reference?)
1>C:\Users\eerhardt\source\repos\ConsoleApp101\ConsoleApp101\Microsoft.Extensions.Configuration.Binder.SourceGeneration\Microsoft.Extensions.Configuration.Binder.SourceGeneration.ConfigurationBindingGenerator\BindingExtensions.g.cs(195,71,195,84): error CS0246: The type or namespace name 'ClientOptions' could not be found (are you missing a using directive or an assembly reference?)
1>C:\Users\eerhardt\source\repos\ConsoleApp101\ConsoleApp101\Microsoft.Extensions.Configuration.Binder.SourceGeneration\Microsoft.Extensions.Configuration.Binder.SourceGeneration.ConfigurationBindingGenerator\BindingExtensions.g.cs(249,71,249,89): error CS0246: The type or namespace name 'TableClientOptions' could not be found (are you missing a using directive or an assembly reference?)

The issue here is that all the Azure SDK libraries put some extensions class in the Microsoft.Extensions.Azure namespace, and the compiler gets confused at this source generated code:

namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
    using Azure.Core;
    using Azure.Data.Tables;

Since it is in Microsoft.Extensions..... it thinks using Azure.Core means using Microsoft.Extensions.Azure and there is no Core namespace in there. I think the other errors are the same as #94065.

@ericstj
Copy link
Member Author

ericstj commented Oct 26, 2023

We need to use a global prefix when importing namespaces here.

@ericstj
Copy link
Member Author

ericstj commented Oct 27, 2023

We should actually never add using statements here. Those using statements are being driven by types referenced across many files, combining all the using statements in a single file can cause name conflicts (even ignoring this special case).

I heard from @captainsafia via @eerhardt

if you always prefix global:: for all types coming from users code, and never let users code add a using statement to your generated code, then you should be good

We need to do this. Any reference to a type without a global:: prefix could face a name conflict, even without local usings - due to global usings.

@captainsafia
Copy link
Member

Yep, here is the configuration we use for displaying type names in RDG.

@eiriktsarpalis eiriktsarpalis self-assigned this Oct 30, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Nov 1, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Nov 2, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Dec 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-Configuration source-generator Indicates an issue with a source generator feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants