The [Obsolete] attribute is a familiar custom attribute that generates a warning when the marked declaration is used, unless the referencing declaration is also marked as [Obsolete]
.
There may be situations where a warning for an experimental API that may be changed or removed later is necessary. The [Obsolete]
attribute may not be the best choice for this, as the error message it generates could mislead users. As an alternative, Metalama provides the ExperimentalAttribute attribute and the Experimental compile-time method, which are better suited for this purpose.
Marking a specific API as experimental
To generate warnings when an experimental API is being used, it is best to use the ExperimentalAttribute attribute. Follow these steps:
Add the
Metalama.Extensions.Architecture
package 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
If you wish to mark several APIs as experimental using a programmatic rule instead of hand-picking declarations, you can use fabrics. Follow these steps:
Add the
Metalama.Extensions.Architecture
package to your project.Create or reuse a fabric type as described in Fabrics.
Import the Metalama.Extensions.Architecture.Fabrics namespace to benefit from extension methods.
Edit the AmendProject, AmendNamespace or AmendType of this 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
29 {
30 public static void Dummy()
31 {
32 // This call is reported.
33 ExperimentalApi.Foo();
34 }
35 }
36}