One or more of these Attributes can be added to an interface's properties. Adding an attribute to a non-compatible property will result in error(s) within the validaiton output.
The following operations can be used for short, int, long, and float property types.
They are also valid on IReadOnlyList of these types. It will verify that every element in the list passes the assertion. If the list is null or of size 0, the asset is considered a pass.
Assert value is greater than the specified value (see Example).
Assert value is greater than or equal to the specified value (see Example).
Assert value is less than the specified value (see Example).
Assert value is less than or equal to the specified value (see Example).
public interface ICurrencyInfo : IBaseInfo
{
[AssertGreater(0)]
int InitialAmount { get; }
[AssertGreaterOrEqual(0f)]
float DropRate { get; }
[AssertLess(0f)]
float SomeMultiplier { get; }
[AssertLessOrEqual(0f)]
IReadOnlyList<float> SomeMultipliers { get; }
}Assert that any IReadOnlyList<T> is not null or empty.
public interface ICurrencyInfo : IBaseInfo
{
[AssertListNotEmpty]
IReadOnlyList<float> DropRates { get; }
}Assert that AssetReference, AssetReferenceSprite, or ParameterReference<T> has an assigned object.
They are also valid on IReadOnlyList of these types. It will verify that every element in the list passes the assertion. If the list is null or of size 0, the asset is considered a pass.
public interface ICurrencyInfo : IBaseInfo
{
[AssertAssignedReference]
ParameterReference<IDropTable> DropTable { get; }
[AssertAssignedReference]
IReadOnlyList<ParameterReference<IDropTable>> BonusDropTables { get; }
[AssertAssignedReference]
AssetReference MainPrefab { get; }
[AssertAssignedReference]
AssetReferenceSprite Icon { get; }
[AssertAssignedReference]
IReadOnlyList<AssetReference> UpgradePrefabs { get; }
[AssertAssignedReference]
IReadOnlyList<AssetReferenceSprite> DooberIcons { get; }
}Asserts that a string or every string in IReadOnlyList<string> matches the regex. If the list is null or of size 0, the asset is considered a pass.
public interface ICurrencyInfo : IBaseInfo
{
[AssertRegex(".*\\.mp3")]
string Sound { get; }
[AssertRegex(".*\\.mp3")]
IReadOnlyList<string> Sounds { get; }
}Asserts that a string, LocalizedString or every string in IReadOnlyList<string> or IReadOnlyList<LocalizedString> is not null or empty. If the list is null or of size 0, the asset is considered a pass.
public interface ICurrencyInfo : IBaseInfo
{
[AssertStringNotEmpty]
string IconResource { get; }
[AssertStringNotEmpty]
LocalizedString DisplayName { get; }
[AssertStringNotEmpty]
IReadOnlyList<string> Resources { get; }
[AssertStringNotEmpty]
IReadOnlyList<LocalizedString> ToolTips { get; }
}To write custom app specific attributes, follow the following steps:
- Create a new assembly (e.g.
MyAssertAttributes) - Reference the assembly
PocketGems.Parameters.Runtimein the new assembly. - Reference the new assembly (e.g.
MyAssertAttributes) from the parameter interface assembly where all of the interfaces are writtenAssets/Parameters/Interfaces/ParameterInterface.asmdef. This is required because only interface & enums can be added directly to theParameterInterface.asmdefassembly.
- Write a subclass of
System.Attributethat implements the parameter'sIValidationAttributeinterface. - At validation time, the following occurs:
CanValidateis first called to validate if the attribute is compatible with a property it's assigned to. This is called once.- if
CanValidateabove is true,WillValidatePropertyis called for any preparation for thepropertyInfo. (e.g. some attributes are compatible with many types, this might be a good oportunity to cache what the current type is). This is called once. Validate(PropertyInfo propertyInfo, object value)is called for every property of every parameter instance. Therefore, this can be called multiple times.
This is a basic example that works on int properties and checks that the value isn't set to a particualr value.
using System.Reflection;
using PocketGems.Parameters.Validation.Attributes;
[System.AttributeUsage(System.AttributeTargets.Property)]
public class MyCustomCheckAttribute : System.Attribute, IValidationAttribute
{
private int _constraint;
public MyCustomCheckAttribute(int constraint)
{
_constraint = constraint;
}
// return true if this attribute can validate the property
public bool CanValidate(PropertyInfo propertyInfo) => propertyInfo.PropertyType == typeof(int);
// any preparation work or caching needed
public void WillValidateProperty(PropertyInfo propertyInfo)
{
}
// called on every instance that has this property
public string Validate(PropertyInfo propertyInfo, object value)
{
if ((int)value == _constraint)
return $"the value cannot be set to {_constraint}";
return null;
}
}Utilize the new attribute on a property.
public interface ICurrencyInfo : IBaseInfo
{
[MyCustomCheck(10)]
int NotTenInt { get; }
}