使用 EmbeddedAttribute 處理一個罕見的情境。
假設有三個專案,專案結構如下:
Solution/
├── ProjectA (類別庫)
│ └── 引用 MySourceGenerator NuGet 套件
└── ProjectB (主程式)
└── 引用 ProjectA
└── 引用 MySourceGenerator NuGet 套件其中 source generator 的 PostInitializationOutput 輸出一個公開的 Attribute
private static void PostInitializationOutput(IncrementalGeneratorPostInitializationContext context)
{
context.AddSource("TestAttribute.g.cs", """
using System;
namespace Embbeded.Test;
public class TestAttribute : Attribute {}
""");
}由於 ProjectA 和 ProjectB 都引用了 MySourceGenerator,所以在兩個專案中都會生成 TestAttribute;而 ProjectB 偏偏又引用了 ProjectA,於是就出現了兩個一模一樣的 TestAttribute。這個現象其實很罕見,在一般的情況下,其實把 TestAttribute 的存取修飾設定為 internal 就沒有問題,但是如果存取修飾非得是 public 或是有 InternalVisibleTo 的情況 ,就會出現 CS0436 的警告。

要解除這個警告的方式就是應用 EmbeddedAttribute,使用這個標籤需要兩道程序。
- 呼叫 IncrementalGeneratorPostInitializationContext.AddEmbeddedAttributeDefinition
- 在輸出的程式碼上掛上 EmbeddedAttribute
所以 PostInitializationOutput 修改成以下,就會解除這個警告
private static void PostInitializationOutput(IncrementalGeneratorPostInitializationContext context)
{
context.AddEmbeddedAttributeDefinition();
context.AddSource("TestAttribute.g.cs", """
using System;
using Microsoft.CodeAnalysis;
namespace Embbeded.Test;
[Embedded]
public class TestAttribute : Attribute {}
""");
}不過這個情境的確非常罕見,大概用到的機會也不太多,只是隨手記錄一下有這玩意而已。