آموزش استفاده AutoMapper در ASP.Net Core

Auto Mapper

 AutoMapper یک کتابخانه در دات‌نت است که برای نگاشت (Map) خودکار اشیاء استفاده می‌شود. این کتابخانه به شما اجازه می‌دهد تا به‌طور خودکار داده‌ها را بین دو نوع مختلف از اشیاء انتقال دهید. این کار می‌تواند بسیار مفید باشد زمانی که می‌خواهید داده‌ها را از مدل‌های دامنه (Domain Models) به مدل‌های نمایش (View Models) یا DTO ها (Data Transfer Objects) منتقل کنید.

ابتدا باید از طریق nuget آن را به پروژه خود اضافه کنید

پکیج :

Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection

اگر از معماری clean architecture استفاده میکنید باید آن را به پروژه Domain خود اضافه کنید. این مقاله اگر Automapper نصب ندارین ،زمانی که پکیج بالا نصب میکنید همراهش Automapper نصب میکنه.

مرحله دوم این هست که باید بریم در فایل startup.cs و در بخش ConfigureServices اتومپر (Automapper) رو صدا بزینم.

مرحله سوم اضافه کردن profile ها ست . یک profile در واقع نقشه (map) هست که میگه چه کلاسی باید به چه کلاسی تبدیل کنی ! حالا ما یک کلاس به نام DomainProfile داریم که در سازندش یک mapping تنظیم شده:

وقتی application اجرا بشه Automapper از طریق کد شما تمام کلاس هایی که از کلاس Profile ارث بری شده پیدا می کند و configuration آنها را load میکند. به همین سادگی به همین خوشمزگی!

مرحله چهار استفاده از IMapper . وقتی پیکربندی (configuration) پروفایل های شما بارگذاری (load) شد. باید interface (واسط) IMapper مانند DI Framework های
دیگر (Dependency Injection) تزریق (Inject) کنید. که این کار رو از طریق سازنده (constructor) انجام میدیم و به همه اشیا نقشه ها دسترسی خواهیم داشت:

دوباره بنظر میرسد کار خارق العاده ای اتفاق افتاده است. ما هیچ وقت IMapper را در ServiceCollection ثبت (register) نکردیم .  اما پکیجی با نام AddAutoMapper که در بخش ConfigureServices ثبت کردیم به صورت اتوماتیک هندل میشود.

دامنه (Scopes)

آخرین چیزی که در نهایت میماند دامنه های داخل Automapper چگونه کار میکنند. پیکربندی های شما (مانند Profile های Automapper ) سینگلتون singleton هستند. به این دلیل که در اجرای برنامه فقط یکبار load میشوند.

واسط IMapper خودش Scoped هست. از نظر ASP.net ، به این معنی است که برای هر درخواست منحصر بفرد(individual) ، یک IMapper جدید ایجاد می شود اما در سرتاسر برنامه برای آن درخواست به اشتراک گذاشته می شود (همون Scope در aspnetcore DI هست) (بر عکس transient که یک درخواست منحصربفرد در سرتاسر برنامه هرزمان آن را تقاضا کند برای آن درخواست نمونه جدید میسازد).بنابراین اگر از IMapper در داخل یک controller و در داخل یک service برای یک درخواست واحد (single request) استفاده کنید ، آنها از همان یک نمونه IMapper استفاده می کنند.

اما چیزی که واقعا مهم است اینکه همه چیز از IValueResolver ، ITypeConverter یا IMemberValueResolver مشتق(derives) شده است، transient scope هستند.آنها همچنین با استفاده از .NET Core Service Collection DI ایجاد می شوند.

کد زیر را ببینید،برای resolve کردن یک mapping خاص استفاده می شود که به وسیله آن می خواهیم یک username براساس id مدل، map سراسری کنیم.برای این کار

از آنجا که این به عنوان نمونه transient با استفاده از .NET Core’s Service Collection ،مخزن ما (repository) نیز به درستی resolve شد و ما قادر خواهیم بود map کردن هایی را انجام دهم که بیش از map کردن سراسری مقادیر ساده باشند.

حال در گیت هاب automapper یک پکیجی را قرار داده که Automapper روی efcore سوار می کنه

آدرس پکیج

این پکیج با پکیجی که قبل تر معرفی کردیم سازگار است و همچنین با DI خود netcore.

به عنوان مثال:

توجه: expressionهای تعریف شده توسط کاربر ، expression های اصلی کلید (primary key) را بازنویسی می کند.

در مورد مقایسه با یک Entity موجود برای بروزرسانی چه می توان گفت؟

پکیج Automapper.Collection.EntityFrameworkCore این کار را از طریق extension method از DbSet انجام می دهد.

ترجمه برابری بین Data Transfer Object (مخفف شدش Dto) و شی EF (همون Entity Framework) به یک expression فقط EF با استفاده از مقادیر dto به عنوان ثابت ها است.

توجه: این کار با تبدیل OrderDTO به Expression <Func <Order، bool ”و استفاده از آن برای پیدا کردن نوع تطبیق در پایگاه داده انجام می شود. همچنین می توانید شیء ها را به expression ها نیز map کنید.

(ارسال تغییرات) submit changes بطور خودکار صدا زده نمیشود.