Create Custom Attributes in C#

Create new folder named Attributes and create new attributes as below:

Create new file named MyClass.cs as below:

using System;

namespace LearnAdvancedCSharpWithRealApps.Attributes
{
	[AttributeUsage(AttributeTargets.Class)]
	public class MyClass : Attribute
	{
		public string Name { get; set; }

		public string Author { get; set; }

		public string DateCreation { get; set; }

		public string Description { get; set; }
	}
}				

Create new file named MyFieldAndProperty.cs as below:

using System;

namespace LearnAdvancedCSharpWithRealApps.Attributes
{
	[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
	public class MyFieldAndProperty : Attribute
	{
		public string Name { get; set; }

		public string Author { get; set; }

		public string DateCreation { get; set; }
	}
}

Create new file named MyMethodAndConstructor.cs as below:

using System;

namespace LearnAdvancedCSharpWithRealApps.Attributes
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor)]
	public class MyMethodAndConstructor : Attribute
	{
		public string Name { get; set; }

		public string Author { get; set; }

		public string DateCreation { get; set; }
	}
}				

Create new file named MinLength.cs as below:

using System;

namespace LearnAdvancedCSharpWithRealApps.Attributes
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
	public class MinLength : Attribute
	{
		public int Value { get; set; }
	}
}

Create new enum named RoleType.cs contains roles for this annotation

namespace LearnAdvancedCSharpWithRealApps.Attributes
{
	public enum RoleType
	{
		Role1, Role2, Role3
	}
}

Create new file named MyRole.cs as below:

using System;

namespace LearnAdvancedCSharpWithRealApps.Attributes
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]
	public class MyRole : Attribute
	{
		public RoleType Value { get; set; }
	}
}

Create Entities folder and create new class named Account.cs as below:

using LearnAdvancedCSharpWithRealApps.Attributes;

namespace LearnAdvancedCSharpWithRealApps.Entities
{
	[MyClass(Name = "Account", Author = "PMK Lab", DateCreation = "2021-03-18", Description = "Description of Account class")]
	public class Account
	{
		[MinLength(Value = 3)]
		[MyFieldAndProperty(Name = "username", Author = "PMK Lab", DateCreation = "2018-03-18")]
		private string username;

		[MyFieldAndProperty(Name = "Address", Author = "PMK Lab", DateCreation = "2018-03-18")]
		public string Address { get; set; }

		[MyFieldAndProperty(Name = "Role", Author = "PMK Lab", DateCreation = "2018-03-18")]
		[MyRole(Value = RoleType.Role2)]
		[MyRole(Value = RoleType.Role3)]
		public string Role { get; set; }

		[MyMethodAndConstructor(Name = "Account", Author = "PMK Lab", DateCreation = "2018-03-18")]
		public Account() { }

		[MyMethodAndConstructor(Name = "Account", Author = "PMK Lab", DateCreation = "2018-03-18")]
		public Account(string username, string address)
		{
			this.username = username;
			Address = address;
		}

		[MyMethodAndConstructor(Name = "ToString", Author = "PMK Lab", DateCreation = "2018-03-18")]
		public override string ToString()
		{
			return base.ToString();
		}

	}
}				
using LearnAdvancedCSharpWithRealApps.Attributes;
using LearnAdvancedCSharpWithRealApps.Entities;
using System;
using System.Reflection;

namespace LearnAdvancedCSharpWithRealApps
{
	class Program
	{
		static void Main(string[] args)
		{
			var account = new Account
			{
				Address = "Address",
				Role = "Role 1"
			};

			Console.WriteLine("Display Custom Annotations of Class");
			DisplayAnnotationsOfClass(account);

			Console.WriteLine("\nDisplay Custom Annotations of Methods");
			DisplayAnnotationsOfMethods(account);

			Console.WriteLine("\nDisplay Custom Annotations of Properties");
			DisplayAnnotationsOfProperties(account);

			Console.WriteLine("\nDisplay Custom Annotations of Fields");
			DisplayAnnotationsOfFields(account);

			Console.WriteLine("\nDisplay Custom Annotations of Constructors");
			DisplayAnnotationsOfConstructors(account);

			Console.ReadLine();
		}

		private static void DisplayAnnotationsOfConstructors(object obj)
		{
			Type type = obj.GetType();
			foreach (ConstructorInfo constructorInfo in type.GetConstructors())
			{
				foreach (object ob in constructorInfo.GetCustomAttributes())
				{
					Console.WriteLine("Constructor " + constructorInfo.GetParameters().Length + " Parameters");
					if (ob is MyMethodAndConstructor)
					{
						var myMethodAndConstructor = ob as MyMethodAndConstructor;
						Console.WriteLine("\tName: " + myMethodAndConstructor.Name);
						Console.WriteLine("\tAuthor: " + myMethodAndConstructor.Author);
						Console.WriteLine("\tDateCreation: " + myMethodAndConstructor.DateCreation);
					}
				}
			}
		}

		private static void DisplayAnnotationsOfFields(object obj)
		{
			Type type = obj.GetType();
			foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance))
			{
				foreach (object ob in fieldInfo.GetCustomAttributes())
				{
					Console.WriteLine("Field Name: " + fieldInfo.Name);
					if (ob is MyFieldAndProperty)
					{
						var myFieldAndProperty = ob as MyFieldAndProperty;
						Console.WriteLine("\tName: " + myFieldAndProperty.Name);
						Console.WriteLine("\tAuthor: " + myFieldAndProperty.Author);
						Console.WriteLine("\tDateCreation: " + myFieldAndProperty.DateCreation);
					}

					if (ob is MinLength)
					{
						var minLength = ob as MinLength;
						Console.WriteLine("\tValue: " + minLength.Value);

					}
				}
			}
		}

		private static void DisplayAnnotationsOfProperties(object obj)
		{
			Type type = obj.GetType();
			foreach (PropertyInfo propertyInfo in type.GetProperties())
			{
				foreach (object ob in propertyInfo.GetCustomAttributes())
				{
					Console.WriteLine("Property Name: " + propertyInfo.Name);
					if (ob is MyFieldAndProperty)
					{
						var myFieldAndProperty = ob as MyFieldAndProperty;
						Console.WriteLine("\tName: " + myFieldAndProperty.Name);
						Console.WriteLine("\tAuthor: " + myFieldAndProperty.Author);
						Console.WriteLine("\tDateCreation: " + myFieldAndProperty.DateCreation);
					}
					if (ob is MyRole)
					{
						var myRole = ob as MyRole;
						Console.WriteLine("\tName: " + myRole.Value);
					}
				}
			}
		}

		private static void DisplayAnnotationsOfMethods(object obj)
		{
			Type type = obj.GetType();
			foreach (MethodInfo methodInfo in type.GetMethods())
			{
				foreach (object ob in methodInfo.GetCustomAttributes())
				{
					if (ob is MyMethodAndConstructor)
					{
						var myMethodAndConstructor = ob as MyMethodAndConstructor;
						Console.WriteLine("\tName: " + myMethodAndConstructor.Name);
						Console.WriteLine("\tAuthor: " + myMethodAndConstructor.Author);
						Console.WriteLine("\tDateCreation: " + myMethodAndConstructor.DateCreation);
					}
				}
			}
		}

		private static void DisplayAnnotationsOfClass(object obj)
		{
			Type type = obj.GetType();
			if (type.GetCustomAttributes(false).Length > 0)
			{
				foreach (object ob in type.GetCustomAttributes(false))
				{
					if (ob is MyClass)
					{
						var myClass = ob as MyClass;
						Console.WriteLine("Name: " + myClass.Name);
						Console.WriteLine("Author: " + myClass.Author);
						Console.WriteLine("DateCreation: " + myClass.DateCreation);
						Console.WriteLine("Description: " + myClass.Description);
					}
				}
			}
		}
	}
}							

Display Custom Annotations of Class
Name: Account
Author: PMK Lab
DateCreation: 2021-03-18
Description: Description of Account class

Display Custom Annotations of Methods
		Name: ToString
		Author: PMK Lab
		DateCreation: 2018-03-18

Display Custom Annotations of Properties
Property Name: Address
		Name: Address
		Author: PMK Lab
		DateCreation: 2018-03-18
Property Name: Role
		Name: Role
		Author: PMK Lab
		DateCreation: 2018-03-18
Property Name: Role
		Name: Role2
Property Name: Role
		Name: Role3

Display Custom Annotations of Fields
Field Name: username
		Value: 3
Field Name: username
		Name: username
		Author: PMK Lab
		DateCreation: 2018-03-18

Display Custom Annotations of Constructors
Constructor 0 Parameters
		Name: Account
		Author: PMK Lab
		DateCreation: 2018-03-18
Constructor 2 Parameters
		Name: Account
		Author: PMK Lab
		DateCreation: 2018-03-18