ساخت اتریبیوتهای سفارشی در #C 🏷
اتریبیوتها راهی برای افزودن متادیتا به کد شما فراهم میکنند. در این پست وبلاگ، ما به اصول اولیه اینکه اتریبیوتها چه هستند، چگونه پراپرتیهای اتریبیوت را تنظیم کنیم، و چگونه محل اعمال اتریبیوتها را پیکربندی کنیم، خواهیم پرداخت. در نهایت، به یک مثال عملی شیرجه خواهیم زد تا نشان دهیم چگونه میتوان از اتریبیوتهای سفارشی در اپلیکیشنها استفاده کرد.
اتریبیوت چیست؟ 🤔
اتریبیوتها در #C راهی برای افزودن اطلاعات اعلانی (declarative) به کد شما هستند. آنها متادیتا فراهم میکنند که میتوان از آن برای کنترل جنبههای مختلف رفتار برنامه شما در زمان اجرا یا زمان کامپایل استفاده کرد.
اتریبیوتها میتوانند به عناصر مختلف برنامه مانند موارد زیر اعمال شوند:
🔹 اسمبلیها، ماژولها، کلاسها، اینترفیسها، استراکتها، enumها
🔹 متدها، سازندهها، delegateها، ایونتها
🔹 پراپرتیها، فیلدها، پارامترها، پارامترهای جنریک، مقادیر بازگشتی
🔹 یا همه عناصر ذکر شده
شما میتوانید یک یا چند اتریبیوت را به این عناصر برنامه اعمال کنید.
شما هر روز هنگام ساخت اپلیکیشن در NET. از اتریبیوتها استفاده میکنید. برای مثال، اتریبیوتهای زیر را بسیار دیدهاید و استفاده کردهاید: 👇
[Serializable]
public class User
{
}
[ApiController]
[Route("api/users")]
public class UsersController : ControllerBase
{
}
چگونه یک اتریبیوت سفارشی بسازیم؟ ✍️
اتریبیوت در #C کلاسی است که از کلاس پایه Attribute ارثبری میکند.
بیایید نگاهی به نحوه ساخت یک اتریبیوت سفارشی بیندازیم:
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class CustomAttribute : Attribute
{
}
[Custom]
public class MyClass
{
}
نام کلاس اتریبیوت باید پسوند Attribute داشته باشد. هنگام اعمال به هر عنصری، این پسوند حذف میشود.
هنگام ایجاد یک کلاس اتریبیوت، شما از یک اتریبیوت داخلی برای مشخص کردن جایی که اتریبیوت میتواند اعمال شود، استفاده میکنید: 🎯
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true)]
public class CustomAttribute : Attribute
{
}
شما میتوانید چندین تارگت را با عملگر | ترکیب کنید تا مشخص کنید یک اتریبیوت کجا میتواند اعمال شود.
پارامتر Inherited نشان میدهد که آیا اتریبیوت سفارشی میتواند توسط کلاسهای مشتق شده به ارث برده شود یا نه. مقدار پیشفرض true است. 🧬
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class CustomInheritedAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class CustomNonInheritedAttribute : Attribute
{
}
هنگام اعمال اتریبیوت inherited به کلاس ParentA، آن توسط کلاس ChildA به ارث برده میشود:
[CustomInherited]
public class ParentA
{
}
public class ChildA : ParentA
{
}
در اینجا، کلاس ChildA یک اتریبیوت CustomInherited دارد. ✅
در حالی که در مثال زیر، هنگام استفاده از یک اتریبیوت non-inherited برای ParentB، آن به کلاس ChildB اعمال نمیشود: ❌
[CustomNonInherited]
public class ParentB
{
}
public class ChildB : ParentB
{
}
پراپرتیهای اتریبیوت ⚙️
پراپرتیهای اتریبیوت میتوانند یا الزامی (پارامترهای اجباری) یا غیرالزامی (پارامترهای اختیاری) باشند. اتریبیوتها میتوانند آرگومانها را به همان روشی که متدها و پراپرتیها میپذیرند، قبول کنند.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false)]
public class CustomWithParametersAttribute : Attribute
{
public string RequiredProperty { get; }
public int OptionalProperty { get; set; }
public CustomWithParametersAttribute(string requiredProperty)
{
RequiredProperty = requiredProperty;
}
}
پراپرتیهای الزامی باید به عنوان پارامترهای سازنده اتریبیوت تعریف شوند. در حالی که غیرالزامیها نباید در سازنده تعریف شوند.
هنگام اعمال چنین اتریبیوتی به یک کلاس، شما باید مقادیر اتریبیوت را به ترتیبی که در سازنده تعریف شدهاند، تنظیم کنید. پراپرتیهای اختیاری باید با نامشان مشخص شوند: 👇
[CustomWithParameters("some text here", OptionalProperty = 5)]
public class ExampleClass
{
}