۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه استفاده از الگوی واحد کار در ASP.NET Core

از واحد الگوی طراحی کار برای ایجاد لایه های دسترسی به داده های انعطاف پذیر، قابل گسترش و قابل استفاده مجدد در برنامه های ASP.NET Core خود بهره ببرید.

از واحد الگوی طراحی کار برای ایجاد لایه های دسترسی به داده های انعطاف پذیر، قابل گسترش و قابل استفاده مجدد در برنامه های ASP.NET Core خود بهره ببرید.

در اکثر برنامه‌های کاربردی تجاری، با انجام عملیات CRUD (ایجاد، خواندن، به‌روزرسانی و حذف)، داده‌ها را از یک فروشگاه داده ذخیره و بازیابی خواهید کرد. در این زمینه، چندین فناوری و ابزار وجود دارد که می توانید از آنها استفاده کنید. برای مثال، می‌توانید از میان چارچوب‌های ORM موجود مانند Entity Framework، Dapper یا NHibernate انتخاب کنید.

با این حال، چالش ها فراتر از ذخیره و بازیابی داده ها است. شما می خواهید از ابزار یا رویکردی استفاده کنید که به شما کمک می کند کد قابل استفاده مجدد، قابل نگهداری و انعطاف پذیر بنویسید. برای این کار، می توانید از الگوهای طراحی مانند مخزن و واحد الگوهای کار استفاده کنید.

ما الگوی طراحی مخزن را در مقاله قبلی اینجا بررسی کردیم. در این مقاله، واحد الگوی طراحی کار را با نمونه‌های کد مرتبط بررسی می‌کنیم تا مفاهیم تحت پوشش را نشان دهیم.

برای استفاده از نمونه کدهای ارائه شده در این مقاله، باید Visual Studio 2022 را در سیستم خود نصب کنید. اگر قبلاً نسخه‌ای ندارید، می‌توانید Visual Studio 2022 را از اینجا بارگیری کنید.

یک پروژه ASP.NET Core 7 Web API در Visual Studio 2022 ایجاد کنید

ابتدا، اجازه دهید یک پروژه ASP.NET Core 7 در Visual Studio 2022 ایجاد کنیم. این مراحل را دنبال کنید:

  1. Visual Studio 2022 IDE را راه اندازی کنید.
  2. روی “ایجاد پروژه جدید” کلیک کنید.
  3. در پنجره “ایجاد پروژه جدید”، “ASP.NET Core Web API” را از لیست الگوهای نمایش داده شده انتخاب کنید.
  4. بعدی را کلیک کنید.
  5. در پنجره “پیکربندی پروژه جدید خود”، نام و مکان پروژه جدید را مشخص کنید.
  6. به صورت اختیاری، بسته به تنظیمات برگزیده خود، کادر انتخاب «قرار دادن راه حل و پروژه در یک فهرست راهنمای» را علامت بزنید.
  7. بعدی را کلیک کنید.
  8. در پنجره «اطلاعات اضافی»، کادری را که می‌گوید «استفاده از کنترل‌کننده‌ها (برای استفاده از حداقل API‌ها علامت آن را بردارید» علامت بزنید، زیرا در این مثال از حداقل API استفاده نمی‌کنیم. “نوع احراز هویت” را به عنوان “هیچ” (پیش‌فرض) بگذارید.
  9. مطمئن شوید که چک باکس‌های «فعال کردن پشتیبانی از API باز کردن»، «پیکربندی برای HTTPS» و «فعال کردن داکر» علامت نخورده باشند زیرا ما از این ویژگی‌ها در اینجا استفاده نخواهیم کرد.
  10. روی ایجاد کلیک کنید.
8 فریمورک جاوا برای دنیای ابری

ما از این پروژه ASP.NET Core 7 Web API برای کار با واحد الگوی طراحی کار در بخش‌های زیر استفاده خواهیم کرد.

واحد الگوی طراحی کار چیست؟

واحد الگوی طراحی کار، یکپارچگی و سازگاری داده ها را در برنامه ها تضمین می کند. این تضمین می کند که تمام تغییرات ایجاد شده در چندین شی در برنامه به پایگاه داده متعهد شده یا به عقب بازگردانده می شود. این یک روش سازمان یافته و سازگار برای مدیریت تغییرات و تراکنش های پایگاه داده ارائه می دهد.

هدف اصلی این الگوی طراحی حفظ سازگاری و اتمی بودن است و اطمینان حاصل می‌کند که همه تغییرات ایجاد شده در پایگاه داده موفقیت‌آمیز هستند یا در صورت بروز مشکل با هم شکست می‌خورند. در نتیجه، سازگاری داده ها حفظ می شود و تغییرات در پایگاه داده همیشه دقیق هستند. با وجود الگوی واحد طراحی کار، توسعه دهندگان می توانند با تمرکز بر منطق تجاری به جای دسترسی و مدیریت پایگاه داده، در زمان و تلاش خود صرفه جویی کنند.

اجرای واحد الگوی طراحی کار در سی شارپ

برای پیاده‌سازی الگوی واحد طراحی کار، باید عملیاتی را که واحد کار در یک رابط یا قرارداد پشتیبانی می‌کند، مشخص کنید و سپس این روش‌ها را در یک کلاس بتن پیاده‌سازی کنید. می‌توانید از هر فناوری دسترسی به داده‌ای که می‌خواهید استفاده کنید، مانند Entity Framework، Dapper، یا ADO.NET استفاده کنید.

یک واحد معمولی اجرای کار شامل اجزای فهرست شده در زیر است:

  • یک واسط برای واحد کار. عملیاتی که واحد کار انجام خواهد داد توسط یک قرارداد یا رابطی تعریف شده است که شامل اعلام همه روش‌های افزودن، تغییر، و حذف داده ها و برای انجام یا بازگرداندن تغییرات در پایگاه داده.
  • اجرای ملموس واحد رابط کار. اجرای ملموس رابطی که هم اکنون توضیح دادیم. این پیاده سازی شامل تمام عملیاتی می شود که هر گونه تراکنش یا عملیات داده را انجام می دهد همراه با عملیات بازگرداندن یا انجام تغییرات.
  • یک کلاس مخزن و رابط آن. کد مورد نیاز برای دسترسی یا اصلاح داده ها در کلاس مخزن و رابط آن موجود است. به عبارت دیگر، شما باید یک کلاس مخزن داشته باشید که از هر یک از متدهای اینترفیس استفاده می کند و یک رابط برای مخزن شما که اقدامات مجاز را مشخص می کند.
چگونه ChatGPT برنامه نویس 100x را فعال می کند

پس، بیایید شروع کنیم!

یک کلاس DbContext سفارشی ایجاد کنید

در Entity Framework یا Entity Framework Core، یک DbContext نشان دهنده دروازه به پایگاه داده است. زیر کلاس DbContext است که می تواند به طور خودکار هنگام استفاده از Entity Framework Core ایجاد شود. ما چندین بار از این کلاس در قطعه کدهای بعدی استفاده خواهیم کرد.

public class CustomDbContext : DbContext
{
    public CustomDbContext(DbContextOptions<CustomDbContext> options)
       : base(options)
    {
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    }
    public DbSet<Author> Authors { get; set; }
}

واسط واحد کار را تعریف کنید

یک فایل .cs جدید با نام IUnitOfWork.cs در پروژه خود ایجاد کنید و کد زیر را وارد کنید.

public interface IUnitOfWork : IDisposable
{
    void Commit();
    void Rollback();
    IRepository<T> Repository<T>() where T : class;
}

واحد کلاس بتن کاری را پیاده سازی کنید

در مرحله بعد، باید پیاده سازی مشخص رابط IUnitOfWork را ایجاد کنید. برای انجام این کار، یک کلاس جدید به نام UnitOfWork در فایلی به همین نام با پسوند cs ایجاد کنید و کد زیر را وارد کنید.

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private readonly DbContext _dbContext;
    private bool _disposed;
    public UnitOfWork(DbContext dbContext)
    {
        _dbContext = dbContext;
    }
    public void Commit()
    {
        _dbContext.SaveChanges();
    }
    public void Rollback()
    {
        foreach (var entry in _dbContext.ChangeTracker.Entries())
        {
            switch (entry.State)
            {
                case EntityState.Added:
                    entry.State = EntityState.Detached;
                    break;
            }
        }
    }
    public IRepository<T> Repository<T>() where T : class
    {
        return new Repository<T>(_dbContext);
    }
    private bool disposed = false;
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                _dbContext.Dispose();
            }
        }
        this.disposed = true;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

رابط مخزن را تعریف کنید

الگوی طراحی مخزن با انتزاع منطق از سایر اجزا و ماژول های برنامه، دسترسی به داده ها را ساده می کند. اشیاء شما بدون نیاز به کار مستقیم با منطقی که برای دسترسی به پایگاه داده زیربنایی استفاده می‌شود، حفظ می‌شوند. به عبارت دیگر، یک مخزن منطق مورد استفاده برای دسترسی به منبع داده را کپسوله می کند.

مرحله بعدی این است که رابط کاربری را برای مخزن خود تعریف کنید. این رابط باید اعلان روش های پشتیبانی شده توسط مخزن را ارائه دهد.

یک رابط جدید به نام IRepository در فایلی به نام IRepository.cs ایجاد کنید و کد تولید شده پیش فرض را با کد زیر جایگزین کنید.

public interface IRepository<T> where T : class
{
    T GetById(object id);
    IList<T> GetAll();
    void Add(T entity);
}

رابط مخزن را پیاده سازی کنید

در نهایت، باید رابط مخزن را که ما ایجاد کردیم پیاده سازی کنید. برای انجام این کار، یک فایل جدید با نام Repository.cs ایجاد کنید و کد پیش فرض تولید شده را با کد زیر جایگزین کنید.

public class Repository<T> : IRepository<T> where T : class
{
    private readonly CustomDbContext _dbContext;
    private readonly DbSet<T> _dbSet;
    public T GetById(object id)
    {
        return _dbSet.Find(id);
    }
    public Repository(DbContext dbContext)
    {
        _dbContext = dbContext;
        _dbSet = _dbContext.Set<T>();
    }
    public IList<T> GetAll()
    {
        return _dbSet.ToList();
    }
    public void Add(T entity)
    {
        _dbSet.Add(entity);
    }
}

DbContext را ثبت کنید

به عنوان یک امتیاز، باید DbContext را به عنوان یک سرویس در فایل Program.cs ثبت کنید تا بتوانید از تزریق وابستگی برای بازیابی نمونه‌های DbContext در کلاس‌های Repository و UnitOfWork استفاده کنید.

نسل افزوده بازیابی، گام به گام

دو راه برای انجام این کار وجود دارد: استفاده از روش AddDbContext یا استفاده از روش AddDbContextPool. روش AddDbContextPool ترجیح داده می شود زیرا استفاده از مجموعه ای از نمونه ها به مقیاس شدن برنامه شما کمک می کند.

builder.Services.AddDbContextPool<CustomDbContext>(o=>o.UseSqlServer("Specify the database connection string here..."));

در این مقاله، یک پیاده‌سازی مخزن عمومی ساختیم که از یک رابط IRepository و کلاس Repository استفاده می‌کند. می توانید با ایجاد کلاسی که رابط عمومی IRepository را مطابق شکل زیر اجرا می کند، یک مخزن برای یک موجودیت خاص ایجاد کنید.

public class AuthorRepository : IRepository<Author>
{
   //Write code here to implement the members of the IRepository interface
}

مخازن و الگوی واحد طراحی کار یک لایه انتزاعی بین منطق کسب و کار شما و لایه دسترسی به داده ایجاد می کنند و زندگی را برای توسعه دهنده بسیار آسان تر می کند. الگوی واحد کار از یک تراکنش یا یک واحد کار برای چندین عملیات درج، به‌روزرسانی و حذف استفاده می‌کند. این عملیات یا به عنوان یک واحد کامل موفق می شوند یا شکست می خورند. به عبارت دیگر، تمام عملیات به صورت یک تراکنش انجام می شود یا به عنوان یک واحد به عقب برگردانده می شود.

در حالی که واحد الگوی کار برای تجمیع چندین عملیات در یک تراکنش استفاده می‌شود، مخازن انواعی را نشان می‌دهند که منطق دسترسی به داده‌ها را محصور می‌کنند و این نگرانی را از برنامه شما جدا می‌کنند.