| Severity | Error |
| Reported by | Metalama.Extensions.Architecture |
| Message | The '<AttributeName>' custom attribute does not define any scope. Set at least one of the following properties: Namespaces, NamespaceOfTypes, Types, TypeNames, CurrentNamespace, or CurrentAssembly. |
Cause
The usage validation attributes CanOnlyBeUsedFromAttribute, CannotBeUsedFromAttribute, InternalsCanOnlyBeUsedFromAttribute, and InternalsCannotBeUsedFromAttribute restrict the code that can use a type or member. The scope of the rule, that is, the code that's allowed or forbidden, is defined by the following properties:
Metalama reports LAMA0904 when none of these properties is set. Other properties, such as Description, ReferenceKinds, or ExclusionPredicateType, don't define a scope, so setting only these properties still causes the error. When this error is reported, the attribute doesn't validate anything. In the message, <AttributeName> is the name of the attribute class, for example CanOnlyBeUsedFromAttribute.
In the following example, the [CanOnlyBeUsedFrom] attribute only sets the Description property.
1using Metalama.Extensions.Architecture.Aspects;
2
3namespace Doc.LAMA0904.Error;
4
5[CanOnlyBeUsedFrom( Description = "Use OrderFactory to create orders." )] // No scope property is set.
Error LAMA0904: The 'CanOnlyBeUsedFromAttribute' custom attribute does not define any scope. Set at least one of the following properties: Namespaces, NamespaceOfTypes, Types, TypeNames, CurrentNamespace, or CurrentAssembly.
6public class Order
7{
8 public decimal Amount { get; set; }
9}
10
11public class OrderFactory
12{
13 public Order Create( decimal amount ) => new Order { Amount = amount };
14}
15
Resolution
Set at least one of the scope properties to define which code is allowed (for [CanOnlyBeUsedFrom]) or forbidden (for [CannotBeUsedFrom]) to use the declaration. If you don't want to restrict the usage of the declaration, remove the attribute.
In the following example, the Types property specifies that only the OrderFactory class can use the Order class.
1using Metalama.Extensions.Architecture.Aspects;
2
3namespace Doc.LAMA0904.Fixed;
4
5[CanOnlyBeUsedFrom( Types = [typeof( OrderFactory )], Description = "Use OrderFactory to create orders." )] // The Types property defines the allowed scope.
6public class Order
7{
8 public decimal Amount { get; set; }
9}
10
11public class OrderFactory
12{
13 public Order Create( decimal amount ) => new Order { Amount = amount };
14}
15