۱۳۸۹/۱۰/۲۰

يافتن نام رشته‌اي كامل يك كلاس در دات نت


دو تنظيم زير را در نظر بگيريد:
<add key="nhibernate-logger" value="NHibernate.Helper.Logging.LoggerFactory, NHibernate.Helper" />
و يا
<add name="StaticContentCacheModule" type="StaticContentCacheModule.StaticCache, StaticContentCacheModule"/>
اين نوع موارد را در فايل‌هاي app.config و يا web.config زياد مي‌توان يافت.
الان فرض كنيد كلاس StaticCache مربوط به StaticContentCacheModule فرضي فوق را به صورت دستي به برنامه‌ي خود اضافه كرده‌ايد. همچنين سطر فوق را نيز بدون هيچ تغييري در قسمت http modules مربوط به web.config برنامه معرفي نموده‌ايد. برنامه را اجرا مي‌كنيد، اما ماژول ذكر شده كار نمي‌كند! چرا؟
چون نام رشته‌اي متناظر با كلاس StaticCache ايي كه اكنون به پروژه‌ي خود اضافه كرده‌ايد، با توجه به فضاهاي نام پروژه‌ي جديد، كاملا دگرگون شده است. بنابراين، سؤال مهم اينجا است كه اين نام را بر اساس تنظيمات پروژه‌ي جاري چگونه مي‌توان يافت؟
خوشبختانه دات نت فريم ورك، ابزاري توكار را براي توليد اين نام رشته‌اي، به همراه دارد:
class Test
{
static void Main()
{
string name = typeof(System.Data.DataView).AssemblyQualifiedName;
Console.WriteLine(name);
}
}
خاصيت AssemblyQualifiedName ذكر شده در مثال فوق، دقيق‌ترين نامي است كه مي‌توانيد در پروژه‌ي خود استفاده نمائيد.
خروجي اين مثال جهت نمايش نام رشته‌اي معادل كلاس System.Data.DataView به صورت زير است:
System.Data.DataView, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

سؤال: از كجا متوجه شوم كه رشته‌ي فوق واقعا كار مي‌كند؟
مقدار متغير name مثال فوق بايد پس از بكارگيري در متد Type.GetType ، حاصلي غير null را بازگشت دهد.
var name = typeof(System.Data.DataView).AssemblyQualifiedName;
var type = Type.GetType(name);
اگر حاصل نال بود، يعني همان مشكلي كه در ابتداي مطلب ذكر شد: ماژول مشخص شده در web.config برنامه توسط رشته‌ي مورد نظر كار نخواهد كرد.

نكته: اگر قصد معرفي اسمبلي ديگري را به برنامه داريد و اين اسمبلي امضاي ديجيتال دارد (strong name signature)، بايد تمام اطلاعات حاصل را ذكر كنيد (مانند مثال فوق كه شامل Version ، Public key token و غيره است). در غير اينصورت (عدم وجود امضاي ديجيتال) ذكر دو قسمت اول خروجي خاصيت AssemblyQualifiedName كافي خواهند بود.