PDA

توجه ! این یک نسخه آرشیو شده می باشد و در این حالت شما عکسی را مشاهده نمی کنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : Attribute ها



TAHA
10-01-2009, 06:35 AM
Attributeها
Attribute ها تگ های توصیفی هستند که اطلاعاتی اضافی در رابطه با عناصر برنامه نویسی فراهم می کنند. منظور از عناصر برنامه چیزهائی مانند کلاس، پروپرتی، فیلد و ... است.

کاربرد ؛ این اطلاعات اضافی در کجا بکار می آیند؟
بسته به نوع Attribute ها کاربرد آنها متفاوت است. بعضی از آنها اطلاعاتی در اختیار کامپایلر جهت نحوه برخورد آن می گذارند. بعضی برای IDE کاربرد دارند مثلا <Browsable> به IDE میفهماند که پروپرتی یا اونت صاحب این صفت در پنجره properties نشان داده شود یا خیر. در LINQ برای تعیین اطلاعات نگاشت بین کلاس های برنامه(Entity) و جداول بانک از Attributeها استفاده می شود.
برنامه نویس هم(منظور خودمان) می تواند اقدام به تعریف Attribute هایی برای مقاصد ویژه اش نماید.
نکاتی در رابطه با Attribute:
-شما می توانید یک یا چند Attribute را برای هر المان برنامه بکار ببرید اعم از اسمبلی، ماژول، کلاس ، پروپرتی ، متد و enum و ....
-در VB ، Attribute ها در < ... > قرار می گیرند. خصوصیات مختلف یک Attribute می تواند با کاما از یکدیگر جدا شوند . مثلاً
<Column(Storage:="_LastName", DbType:="NVarChar(20) NOT NULL", _
CanBeNull:=false)> _
-Attribute ها می توانند آرگومان بپذیرند. ارگومانها می تواند به دو روش ارسال گردد(این امر به تعریفAttribute نیز بستگی دارد)
1- به عنوان پارامترهای سازنده کلاس و به ترتیب تعریف شده



<CustomAttr(True, False)> Class Class1
2- با استفاده از نام آرگومانها(با استفاده از ":=" )(دیگر ترتیب آوردن آنها مهم نیست)



<CustomAttr(Update:=True, Keep:=False)> Class Class1
لازم بذکر است در زمانیکه سازنده کلاس Attribute(constructor of attribute classes) نیاز به آرگومان دارد باید آرگومانها بصورت ترتیبی(positional arguments)آورده شوند و آرگومانهای با نام (Named arguments) تنها برای مقدار دادن به فیلدها و پروپرتی های Attribute کاربرد دارند.(گیج نشوید، کمی صبر کنید متوجه خواهید شد که Attribute نیز یک کلاس است که می تواند سازنده، پروپرتی ، فیلد و حتی متد داشته باشد)
-آرگومانها می تواند اجباری یا اختیاری باشد.
نکته کوچک: Attribute و المان موصوف آن بایددر یک خط باشد ، اگر خواستید در دو خط بنویسید underline را فراموش نکنید.

مثال: Attribute های مشهور و پرکاربرد(البته از دید بنده)
<webMethod> : در وب سرویس ها، متدهائی را که باید قابل فراخوانی باشند (بطور علمی: براساس پروتکل SOAP قابل فراخوانی باشند) مشخص می کند.
<DllImport> برای فراخوانی کدهای unmanaged کاربرد دارد مثلا استفاده از dll ای که به زبان VB6 نوشته شدهاست.
<Browsable> همانطور که گفتیم مشخص می کند آیا پرو پرتی یا اونت باید در پنجره Properties ویژوال استادیو نمایش یابد یا خیر.
<Table> کاربرد در LINQ، برای نگاشت یک کلاس با جدولی در بانک
و ...

چطور یک Attribute مخصوص خود بسازیم؟
Attribute ها در واقع یک کلاس هستند که از System.Attribute ارث برده اند. عموماً Attribute ها دارای پروپرتی هایی هستند که توسط آنها اطلاعاتی را در رابطه با المانشان ذخیره می کنند. این اطلاعات هنگامی که قصد استفاده از Attribute را داریم بکار می آید.
کد:

Class TestAttribute
Inherits System.Attribute

Private m_SomeValue As String

Public Sub New(ByVal Value As String)
m_SomeValue = Value
End Sub
Public Sub Attr(ByVal AttrValue As String)
'Add method code here.
End Sub
Public Property SomeValue() As String ' A named parameter.
Get
Return m_SomeValue
End Get
Set(ByVal Value As String)
m_SomeValue = Value
End Set
End Property
End Class
بیائید با یک مثال کاربرد، تعریف و طریقه استفاده از Attribute را بررسی کنیم(این مثال فقط یک مثال است)

فرض کنید کلاس های مختلفی با فیلدهای گوناگون داریم که اطلاعات داخل آن فیلدها را باید در بانک وارد نمائیم. در هر کلاس توابعی داریم که وظیفه اعتبارسنجی (validation) فیلدها را بر عهده دارند. قبل از اینسرت داده های یک شی باید از معتبر بودن داده ها (فیلدها) مطمئن شویم یعنی تمام توابع اعتبارسنجی را فراخوانی نموده و در صورتی که همگی True برگردانند آنگاه اقدام به اینسرت داده های آن شی در بانک نمائیم.
راه اول: در هر کلاس تابعی بنویسیم که تمام توابع اعتبارسنجی را فراخوانی نموده و نتیجه آنها را بررسی نماید(All validation). راه حل بدی نیست، اما اگر بعد از نوشتن این تابع ، یک تابع اعتبارسنجی دیگر نوشتیم و یادمان رفت آن را در تابع All validation فراخوانی کنیم چه می شود! در ضمن برای نوشتن یک روتین ثابت که همیشه قبل از اینسرت هر کلاسی رخ دهد و وظیفه اعتبارسنجی را عهده دار باشد کار ما سخت خواهد شد.

راه دوم: توابع مربوط به اعتبارسنجی کلاسها را با یک Attribute خاص مشخص کنیم. حال قبل از اینسرت هر شی ای از هر کلاسی، کافی است توابع آن را با Reflection استخراج نموده و آن هائی را که دارای Attribute خاص مورد نظر ما هستند فراخوانی Invoke نمائیم.
تعریف Attribute خاص خودمان:
کد:

Public Class MKHValidation
Inherits Attribute
'برای کار مثال ما چیز دیگری لازم نیست
End Class
مشخص کردن توابع اعتبارسنجی کلاس با Attribute خاص
کد:

Public Class testEntity

Public name As String
Public KodMeli As String
Public Age As Integer

<MKHValidation()> _
Public Function Name_Validation() As Boolean
If name.Length > 0 And name.Length < 30 Then
Return True
Else
Return False
End If
End Function

<MKHValidation()> _
Public Function KodMeli_Validation() As Boolean
'کد ملی ده کارکتر عددی است
If KodMeli.Length = 10 And IsNumeric(KodMeli) Then
Return True
Else
Return False
End If
End Function

<MKHValidation()> _
Public Function Age_Validation() As Boolean
If Age > 0 Then
Return True
Else
Return False
End If
End Function
End Class
نوشتن روالی که اعتبارسنجی هر شی ای از هر کلاسی را انجام میدهد:
کد:

''' <summary>
''' تمام متدهای مربوط به اعتبارسنجی یک شی فراخوانی می شود
''' </summary>
''' <param name="entity">شی مورد نظر</param>
Public Function ChechEntityValidation(ByVal entity As Object) As Boolean

Dim typEntity As Type = entity.GetType
'تمام متدهای شی را بدست می آوریم
Dim AllMethod() As MethodInfo = typEntity.GetMethods(BindingFlags.Instance Or _
BindingFlags.Public Or _
BindingFlags.NonPublic)


For Each metod As MethodInfo In AllMethod

'بررسی اینکه آیا متد صفت مورد نظر را دارد
Dim Atr As Attribute = Attribute.GetCustomAttribute(metod, GetType(MKHValidation))

If Atr IsNot Nothing Then

'فراخوانی متد
Dim result As Object
result = metod.Invoke(entity, Nothing)

If result <> True Then
Return False
End If

End If

Next

Return True

End Function


امیدوارم مفید واقع شود