mostafavakili.ir
تبدیلType استفاده شده در Expression ها با استفاده از ExpressoinVisitor
اگه بخوام ادامه مسیر قبلی رو برم و طبق قولی که دادم بودم عمل کنم امروز میخوام توضیح بدم چطوری Expression ها رو از یه نوعی به نوع دیگه تبدیل کردم, ولی قبلش به نظرم بهتره تا کمی دلیل این کار رو توضیح بدم بعد ادامه بدم, وقتی قرار شد تا فریم ورک موجود رو بهبود بدم و اصلاح کنم یه موضوعی بود که باعث شده بود تا کلی کد اضافی داخل این پروژه زده بشه, برنامه نویس های قبلی سعی کرده بودن زیر ساخت رو طراحی کنن که کسی که داره لایه سرویس رو مینویسه بر اساس مدل های خودش Expression ها رو بنویسه و همون رو به لایه رپوزیتوری بده و این Expression ها به صورت خودکار به مدل های دیتابیسی مپ بشن ولی موفق نشده بودن واسه همین بعد از گذشت یه بازه زمانی به این نتیجه رسیده بودن که باید کلاس های پایه سرویس و رپوزیتوری جدید اضافه کنن و کلی از کد ها رو عوض کنن , درنهایت ما کلی متد داشتیم که کار نمیکرد و وقتی یه نیروی تازه وارد میخواست روی این کد ها توسعه انجام بده بدون خبر داشتن از این ماجرا میومد کلی کد میزد و موقع اجرا میدید که همه چیز به خطا میخوره و باید حتمادقت میکرد که از کدوم کلاس های پایه داره ارث بری میکنه
خب مشکل اصلی چی بود, تیم قبلی تصمیم میگیره تا لایه Repository رو کامل از لایه سرویس جداکنه, پس تصمیم میگیره تا یه کلاس مدل رو تعریف کنه که صرفا مدل های Entity framework رو شامل بشه و اومده بود یه سری کلا های جدید تعریف کرده بود که توی لایه Service و به عنوان ViewModel ازش استفاده کرده بود تمام ورودی های مربوط به Service ها از نوع ViewModel بود و تمام ورودی های Respository از نوع Model, خب این معماری تنها تا وقتی که تنها عملیات Crud مد نظر بود خیلی خوب عمل میکرد ولی از یک جایی به بعد این نیاز توی پروژه ها به وجود اومده بود که یک سری متد داشته باشیم که قرار بود یک سری Expression رو دریافت کنن و بر اساس اون داده ها رو فیلتر کنن, که باعث شده بود کلا ساختار ها به هم بریزه برای این که درک بهتری از این موضوع داشته باشین تصویر پایین رو ببینید
همون طوری که توی تصویر بالا میبنید ما یک Expression داریم که برا اساس ViewModel ساخته شده و چیزی که باید به متد LoadDb بدیم حتما باید از نوع Model باشه.
خب برای اینکه بدونین این رو چطوری هندل کردیم کلاس های پایین رو در نظر بگیرین, من اسامی رو طوری انتخاب کردم که قابل درک باشه(من اینجا مدل ها رو خیلی ساده کردم و تنها هدفم نشون دادن روش هستش نه تمام کدی که پیاده سازی شده)
خب الان میخوایم این Expression رو که بر اساس ViewModel پیاده سازی شده رو به صورت خودکار تبدیل کنیم به یه Expression دیگه بر اساس Model:
برای این که بتونیم این کار رو انجام بدیم اولین چیزی که نیاز داریم این هستش که یک کلاس برای این منظور طراحی کنیم که باز من رفتم سراغ کلاس های Generic:
یه متد به منظور تبدیل به صورت استاتیک اضافه کردیم(اگر میخواین دلیلشو بدونین بهتره مقاله قبلی رو بخونین), کاری که باید انجام میدادیم این بود که اول نوع ورودی رو پیدا کنیم و پارامتر جدید رو بر اساس اون تشکیل بدیم, وقتی پارامتر جدید رو بر اساس Model ایجاد کردیم باید یک زیر ساختی داشته باشیم که کل بدنه این Expression رو پردازش کنه و عملیات تبدیل رو انجام بده, وقتی این تبدیل روی بدنه درخواست انجام شد در نهایت Body جدید رو با پارامتر تعریف شده ترکیب میکنیم تا به یه Expression جدید از نوع Model برسیم و برگردونیم و به راحتی میدیمش به لایه Repository
و اما چطوری Body رو تبدیل کردیم, وقتی که Linq و ExpressoinTree معرفی شد هدفش این بود که برنامه نویس بتونه داخل کدهاش کد بنویسه و بتونه در زمان اجرای کدهای جدید ایجاد و اجرا بکنه, برای اینکه بشه این ساختار رو در زمان اجرا هم پردازش کرد و بشه تغییراتی رو بهش اعمال کرد توی دات نت 3.5 یک کلاسی معرفی شد به اسم ExpressionVisitor, این کلاس شامل تمام متد های مورد نیاز برای پردازش node های مربوط به Expression tree هستش و به ما اجازه میده هر تغییری رو توی هر سطحی که بخوایم روی Expression انجام بدیم.
خب با وجود همچین کلاسی کار ما خیلی ساده تر شد و اومدیم کلاس پایین رو ایجاد کردیم که کار Convert رو برامون انجام میداد
در نهایت نتیجه این تغییرات موقع اجرا شد چیزی که دنبالش بودیم:
فعلا این باشه تا یادم بود بعدا ویرایش کنم و مطالب رو کمی بیشتر بازش کنم
مطلبی دیگر از این انتشارات
پیشبینی سال ۲۰۱۹ در حوزه اینترنت اشیا
مطلبی دیگر از این انتشارات
داستان gREST؛ گراف دیتابیس و Restful API
مطلبی دیگر از این انتشارات
Web Slice ها در Internet Explorer 8.0