The [Obsolete] attribute generates a warning when the marked declaration is used, unless the referencing declaration is also marked as [Obsolete].
Sometimes you need a warning for an experimental API that may change or be removed later. The [Obsolete] attribute isn't ideal because its error message could mislead users. Instead, Metalama provides the ExperimentalAttribute attribute and the Experimental compile-time method for this purpose.
Marking a specific API as experimental
To generate warnings when an experimental API is used, it's best to use the ExperimentalAttribute attribute. Follow these steps:
Add the
Metalama.Extensions.Architecturepackage to your project.Annotate the API with the ExperimentalAttribute.
Example: Using the Experimental attribute
In the following example, the ExperimentalApi class is explicitly marked as experimental.
1using Metalama.Extensions.Architecture.Aspects;
2
3namespace Doc.Architecture.Experimental;
4
5[Experimental]
6public static class ExperimentalApi
7{
8 public static void Foo() { }
9
10 public static void Bar()
11 {
12 // This call is allowed because we are within the experimental class.
13 Foo();
14 }
15}
16
17internal static class ProductionCode
18{
19 public static void Dummy()
20 {
21 // This call is reported.
Warning LAMA0900: The 'ExperimentalApi' type is experimental.
22 ExperimentalApi.Foo();
23 }
24}
Programmatically marking APIs as experimental
To mark several APIs as experimental using a programmatic rule instead of hand-picking declarations, use fabrics. Follow these steps:
Add the
Metalama.Extensions.Architecturepackage to your project.Create or reuse a fabric type as described in Fabrics.
Import the Metalama.Framework.Fabrics and Metalama.Extensions.Architecture namespaces to benefit from extension methods.
Edit the AmendProject, AmendNamespace, or AmendType method.
Select the experimental APIs using the Select, SelectMany, and Where methods.
Call the Experimental method.
Example: Using the Experimental compile-time method
In the following example, all public members of ExperimentalNamespace are programmatically marked as experimental.
1using Doc.Architecture.Experimental_Fabric.ExperimentalNamespace;
2using Metalama.Extensions.Architecture;
3using Metalama.Framework.Code;
4using Metalama.Framework.Fabrics;
5
6namespace Doc.Architecture.Experimental_Fabric
7{
8 namespace ExperimentalNamespace
9 {
10 internal class Fabric : NamespaceFabric
11 {
12 public override void AmendNamespace( INamespaceAmender amender )
13 {
14 amender.SelectTypes()
15 .Where( t => t.Accessibility == Accessibility.Public )
16 .Experimental();
17 }
18 }
19
20 public static class ExperimentalApi
21 {
22 public static void Foo() { }
23 }
24 }
25
26 internal static class ProductionCode
27 {
28 public static void Dummy()
29 {
30 // This call is reported.
Warning LAMA0900: The 'ExperimentalApi' type is experimental.
31 ExperimentalApi.Foo();
32 }
33 }
34}
1using Doc.Architecture.Experimental_Fabric.ExperimentalNamespace;
2using Metalama.Extensions.Architecture;
3using Metalama.Framework.Code;
4using Metalama.Framework.Fabrics;
5
6namespace Doc.Architecture.Experimental_Fabric
7{
8 namespace ExperimentalNamespace
9 {
10
11#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
12
13 internal class Fabric : NamespaceFabric
14 {
15 public override void AmendNamespace(INamespaceAmender amender) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
16 }
17
18#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
19
20
21
22 public static class ExperimentalApi
23 {
24 public static void Foo() { }
25 }
26 }
27
28 internal static class ProductionCode
Warning LAMA0900: The 'ExperimentalApi' type is experimental.
29 {
30 public static void Dummy()
31 {
32 // This call is reported.
33 ExperimentalApi.Foo();
34 }
35 }
36}