MetalamaConceptual documentationVerifying architectureMarking an API as experimental
Open sandboxFocusImprove this doc

Marking experimental APIs

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:

  1. Add the Metalama.Extensions.Architecture package to your project.

  2. 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]
6    public 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
17    internal 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    }
25}

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:

  1. Add the Metalama.Extensions.Architecture package to your project.

  2. Create or reuse a fabric type as described in Fabrics.

  3. Import the Metalama.Extensions.Architecture.Fabrics namespace to benefit from extension methods.

  4. Edit the AmendProject, AmendNamespace or AmendType of this method. Begin by calling amender.Verify().

  5. Select the experimental APIs using the Select, SelectMany and Where methods.

  6. 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.

Source Code
1using Doc.Architecture.Experimental_Fabric.ExperimentalNamespace;
2using Metalama.Extensions.Architecture.Fabrics;
3using Metalama.Framework.Code;
4using Metalama.Framework.Fabrics;
5using System.Linq;
6
7namespace Doc.Architecture.Experimental_Fabric
8{
9    namespace ExperimentalNamespace
10    {
11        internal class Fabric : NamespaceFabric
12        {



13            public override void AmendNamespace( INamespaceAmender amender )
14            {
15                amender.Verify().Types().Where( t => t.Accessibility == Accessibility.Public ).Experimental();
16            }
17        }
18
19        public static class ExperimentalApi



20        {
21            public static void Foo() { }
22        }
23    }
24
25    internal static class ProductionCode
26    {
27        public static void Dummy()
28        {
29            // This call is reported.
            Warning LAMA0900: The 'ExperimentalApi' type is experimental.

30            ExperimentalApi.Foo();
31        }
32    }
33}
Transformed Code
1using Doc.Architecture.Experimental_Fabric.ExperimentalNamespace;
2using Metalama.Extensions.Architecture.Fabrics;
3using Metalama.Framework.Code;
4using Metalama.Framework.Fabrics;
5using System.Linq;
6
7namespace Doc.Architecture.Experimental_Fabric
8{
9    namespace ExperimentalNamespace
10    {
11
12#pragma warning disable CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
13
14        internal class Fabric : NamespaceFabric
15        {
16            public override void AmendNamespace(INamespaceAmender amender) => throw new System.NotSupportedException("Compile-time-only code cannot be called at run-time.");
17        }


18
19#pragma warning restore CS0067, CS8618, CS0162, CS0169, CS0414, CA1822, CA1823, IDE0051, IDE0052
20
21
22
23        public static class ExperimentalApi
24        {
25            public static void Foo() { }
26        }
27    }
28
29    internal static class ProductionCode
30    {
31        public static void Dummy()
32        {
33            // This call is reported.
34            ExperimentalApi.Foo();
35        }
36    }
37}