Wjybxx.Commons.Poet 1.4.5

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Wjybxx.Commons.Poet --version 1.4.5
                    
NuGet\Install-Package Wjybxx.Commons.Poet -Version 1.4.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Wjybxx.Commons.Poet" Version="1.4.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Wjybxx.Commons.Poet" Version="1.4.5" />
                    
Directory.Packages.props
<PackageReference Include="Wjybxx.Commons.Poet" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Wjybxx.Commons.Poet --version 1.4.5
                    
#r "nuget: Wjybxx.Commons.Poet, 1.4.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Wjybxx.Commons.Poet@1.4.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Wjybxx.Commons.Poet&version=1.4.5
                    
Install as a Cake Addin
#tool nuget:?package=Wjybxx.Commons.Poet&version=1.4.5
                    
Install as a Cake Tool

Csharp-Poet

Poet包是javapoet仓库的移植版。 我在java端使用javapoet生成各类辅助类已有5年左右,这是个非常好用的轮子的,但C#端没有合适的等价物,于是自己移植了一版。

用言语描述Poet包不够直观,我们直接看代码生成器和生成的代码(可运行测试用例)(代码生成器的最佳示例可见Dson和BTree库)。

GeneratorTest测试类(生成器)代码如下:

    private static TypeSpec BuildClassType() {
        TypeName dictionaryTypeName = TypeName.Get(typeof(LinkedDictionary<string, object>));
        AttributeSpec processorAttribute = AttributeSpec.NewBuilder(ClassName.Get(typeof(GeneratedAttribute)))
            .Constructor(CodeBlock.Of("$S", "GeneratorTest")) // 字符串$S
            .Build();

        AttributeSpec attributeSpec = AttributeSpec.NewBuilder(ClassName.Get(typeof(MyCodeAttribute)))
            .AddMember("Name", CodeBlock.Of("$S", "wjybxx"))
            .AddMember("Age", CodeBlock.Of("29"))
            .Build();

        TypeSpec classType = TypeSpec.NewClassBuilder("ClassBean")
            .AddModifiers(Modifiers.Public)
            .AddAttribute(processorAttribute)
            .AddAttribute(attributeSpec)
            // 字段
            .AddField(TypeName.INT, "age", Modifiers.Private)
            .AddField(TypeName.STRING, "name", Modifiers.Private)
            .AddSpec(FieldSpec.NewBuilder(dictionaryTypeName, "blackboard", Modifiers.Public | Modifiers.Readonly)
                .Initializer("new $T()", dictionaryTypeName)
                .Build())
            // 构造函数
            .AddSpec(MethodSpec.NewConstructorBuilder()
                .AddModifiers(Modifiers.Public)
                .ConstructorInvoker(CodeBlock.Of("this($L, $S)", 29, "wjybxx"))
                .Build())
            .AddSpec(MethodSpec.NewConstructorBuilder()
                .AddModifiers(Modifiers.Public)
                .AddParameter(TypeName.INT, "age")
                .AddParameter(TypeName.STRING, "name")
                .Code(CodeBlock.NewBuilder()
                    .AddStatement("this.age = age")
                    .AddStatement("this.name = name")
                    .Build())
                .Build())
            // 属性
            .AddSpec(PropertySpec.NewBuilder(TypeName.INT, "Age", Modifiers.Public)
                .Getter(CodeBlock.Of("age").WithExpressionStyle(true))
                .Setter(CodeBlock.Of("age = value").WithExpressionStyle(true))
                .Build())
            .AddSpec(PropertySpec.NewBuilder(TypeName.BOOL, "IsOnline", Modifiers.Private)
                .Initializer("$L", false)
                .Build()
            )
            // 普通方法
            .AddSpec(MethodSpec.NewMethodBuilder("Sum")
                .AddDocument("求int的和")
                .AddModifiers(Modifiers.Public)
                .Returns(TypeName.INT)
                .AddParameter(TypeName.INT, "a")
                .AddParameter(TypeName.INT, "b")
                .Code(CodeBlock.NewBuilder()
                    .AddStatement("return a + b")
                    .Build())
                .Build())
            .AddSpec(MethodSpec.NewMethodBuilder("SumNullable")
                .AddDocument("求空int的和")
                .AddModifiers(Modifiers.Public | Modifiers.Extern)
                .Returns(TypeName.INT.MakeNullableType())
                .AddParameter(TypeName.INT.MakeNullableType(), "a")
                .AddParameter(TypeName.INT, "b")
                .Build())
            .AddSpec(MethodSpec.NewMethodBuilder("SumRef")
                .AddDocument("求ref int的和")
                .AddModifiers(Modifiers.Public | Modifiers.Extern)
                .Returns(TypeName.INT)
                .AddParameter(TypeName.INT.MakeByRefType(), "a")
                .AddParameter(TypeName.INT.MakeByRefType(ByRefTypeName.Kind.In), "b")
                .Build())
            .Build();
        return classType;
    }

下面是测试GeneratorTest类生成的代码:

    using Wjybxx.Commons.Attributes;
    using Commons.Tests.Apt;
    using Wjybxx.Commons.Collections;
    
    namespace Wjybxx.Commons.Apt;
    
    [Generated("GeneratorTest")]
    [MyCode(Name = "wjybxx", Age = 29)]
    public class ClassBean 
    {
      private int age;
      private string name;
      public readonly LinkedDictionary<string, object> blackboard = new LinkedDictionary<string, object>();
    
      public ClassBean()
       : this(29, "wjybxx") {
      }
    
      public ClassBean(int age, string name) {
        this.age = age;
        this.name = name;
      }
    
      public int Age {
        get => age;
        set => age = value;
      }
    
      private bool IsOnline { get; set; } = false;
    
      /// <summary>
      /// 求int的和
      /// </summary>
      public int Sum(int a, int b) {
        return a + b;
      }
    
      /// <summary>
      /// 求空int的和
      /// </summary>
      public extern int? SumNullable(int? a, int b);
    
      /// <summary>
      /// 求ref int的和
      /// </summary>
      public extern int SumRef(ref int a, in int b);
    }

版本号同步

注意:该程序集总是和Wjybxx.Commons.Apt版本号保持一致,不论该程序集是否发生变化。

ReleaseNotes

1.4.0

  1. 删除TypeVariableName,新增TypeParameterSpecTypeParameterName,新的Name仅表达对泛型变量的引用,不包含泛型约束条件。
  2. TypeName变更为抽象类,基础类型也由ClassName表达。

在之前的版本中,TypeName是参照JavaPoet实现的;但随着使用的增多,发现JavaPoet的TypeVariableName设计问题很大。 TypeName的初衷是对目标类型的引用,但TypeVariableName却包含了对泛型变量的约束,这导致了一些复杂的问题。

1.3.1

bug fix

1.修复attribute无构造器时,生成代码会多一个逗号问题

1.3.0

  1. Poet从Commons.Apt中拆分出来,成为独立的无依赖的程序集 -- 不再依赖Commons.Core项目。
  2. 修改了属性PropertySepc的Modifier管理,拆分为明确的gettersetter
  3. 统一工厂方法为Get
  4. TypeName为Roslyn做了一些兼容支持
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • net6.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Wjybxx.Commons.Poet:

Package Downloads
Wjybxx.Commons.Apt

注解处理器工具

Wjybxx.Dson.Apt

Dson注解处理器,代码生成工具

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.5.0-rc1 153 7/1/2025
1.4.5 179 6/14/2025
1.4.4 206 5/27/2025
1.4.3 165 5/25/2025
1.4.2 109 5/24/2025
1.4.1 281 5/15/2025
1.4.0 262 5/14/2025
1.3.2 232 5/12/2025
1.3.1 182 5/8/2025
1.3.0 181 5/6/2025