بررسی Source Generators در #C - قسمت چهارم - روش دسترسی به تنظیمات برنامه
نویسنده: وحید نصیری
تاریخ: ۱۴۰۱/۰۵/۱۹ ۱۲:۵۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<Project>
<ItemGroup>
<CompilerVisibleProperty Include="SourceGenerator_CustomRootNamespace"/>
</ItemGroup>
</Project> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <!-- Generates a package at build -->
<IncludeBuildOutput>false</IncludeBuildOutput> <!-- Do not include the generator as a lib dependency -->
</PropertyGroup>
<ItemGroup>
<!-- Package the generator in the analyzer directory of the nuget package -->
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/>
<!-- Package the props file -->
<None Include="NotifyPropertyChangedGenerator.props" Pack="true" PackagePath="build" Visible="true"/>
</ItemGroup>
</Project> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<SourceGenerator_CustomRootNamespace>ThisIsTest</SourceGenerator_CustomRootNamespace>
</PropertyGroup>
<ItemGroup>
<CompilerVisibleProperty Include="SourceGenerator_CustomRootNamespace"/>
</ItemGroup>
</Project> internal static class SourceGeneratorContextExtensions
{
public static string GetMSBuildProperty(
this GeneratorExecutionContext context,
string property,
string defaultValue = "")
{
return !context.AnalyzerConfigOptions.GlobalOptions.TryGetValue($"build_property.{property}", out var value)
? defaultValue
: value;
}
} [Generator]
public class NotifyPropertyChangedGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
}
public void Execute(GeneratorExecutionContext context)
{
var customRootNamespace = context.GetMSBuildProperty("SourceGenerator_CustomRootNamespace", "Test"); <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<AdditionalFiles Include="file1.txt" Visible="false"/>
</ItemGroup>
</Project> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<AdditionalFiles Include="file2.txt" SourceGenerator_EnableLogging="true" Visible="false"/>
</ItemGroup>
</Project> <Project>
<ItemGroup>
<CompilerVisibleProperty Include="SourceGenerator_CustomRootNamespace"/>
<CompilerVisibleProperty Include="SourceGenerator_EnableLogging"/>
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="SourceGenerator_EnableLogging"/>
</ItemGroup>
</Project> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<SourceGenerator_EnableLogging>true</SourceGenerator_EnableLogging>
</PropertyGroup>
<ItemGroup>
<CompilerVisibleProperty Include="SourceGenerator_EnableLogging"/>
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="SourceGenerator_EnableLogging"/>
<AdditionalFiles Include="file1.txt" Visible="false"/> <!-- logging will be controlled by default, or global value -->
<AdditionalFiles Include="file2.txt" SourceGenerator_EnableLogging="true" Visible="false"/> <!-- always enable logging for this file -->
<AdditionalFiles Include="file3.txt" SourceGenerator_EnableLogging="false" Visible="false"/> <!-- never enable logging for this file -->
</ItemGroup>
</Project> internal static class SourceGeneratorContextExtensions
{
public static string GetAdditionalFilesOption(
this GeneratorExecutionContext context,
AdditionalText additionalText,
string property,
string defaultValue = "")
{
return !context.AnalyzerConfigOptions.GetOptions(additionalText)
.TryGetValue($"build_metadata.AdditionalFiles.{property}", out var value)
? defaultValue
: value;
}
} [Generator]
public class NotifyPropertyChangedGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
}
public void Execute(GeneratorExecutionContext context)
{
var customRootNamespace = context.GetMSBuildProperty("SourceGenerator_CustomRootNamespace", "Test");
var globalLoggingSwitch = context.GetMSBuildProperty("SourceGenerator_EnableLogging", "false");
var emitLoggingGlobal = globalLoggingSwitch.Equals("true", StringComparison.OrdinalIgnoreCase);
foreach (var file in context.AdditionalFiles)
{
var perFileLoggingSwitch = context.GetAdditionalFilesOption(file, "SourceGenerator_EnableLogging");
var emitLogging = string.IsNullOrWhiteSpace(perFileLoggingSwitch)
? emitLoggingGlobal // allow the user to override the global logging on a per-file basis
: perFileLoggingSwitch.Equals("true", StringComparison.OrdinalIgnoreCase);
// add the source with or without logging...
}