Secara singkat tentang di mana menempatkan Repositori di Onion Architeckture dan DDD


Halo Habr. Saya ingin berbicara tentang di mana, pada gambar di atas, meletakkan repositori. Sedikit lebih banyak tentang DIP, IOC dan struktur proyek. Ada pendekatan standar yang menurutnya antarmuka IRepository harus dicegah di lapisan domain ke DomainServices dan implementasi dalam Infrastruktur. Di sini kita berbicara tentang Repositori standar yang hanya merupakan kumpulan abstrak objek yang tidak tahu tentang transaksi dan UnitOfWork dan sebagainya (misalnya, IList dan versi generiknya adalah antarmuka khas repositori abstrak). Saya pribadi tidak setuju dengannya karena biasanya repositori ditumbuhi dengan perilaku khusus untuk aplikasi tertentu, jadi saya meletakkan antarmuka mereka ke ApplicationServices. Implementasi tentu saja tetap di lapisan Infrastruktur. Jika Anda tertarik, selamat datang di kucing.

Seringkali banyak yang bingung dengan gambar lama dari Robert Martin:

Dia memiliki kata-kata dalam artikel
Entitas merangkum aturan bisnis perusahaan yang luas. Entitas dapat berupa objek dengan metode, atau dapat berupa sekumpulan struktur dan fungsi data. Tidak masalah asalkan entitas dapat digunakan oleh banyak aplikasi berbeda di perusahaan.

Oleh karena itu, ternyata itu hanya memberikan DomainServices ke lapisan Entitas. Baiklah, UseCases == ApplicationServices. Gateway == UserPepository, EmailService, Logger. Baca lebih lanjut di sini .

  1. Serivice adalah kelas tanpa kewarganegaraan. InfrastructureService adalah anti-korupsi laer yang mengisolasi Anda dari sistem file, perpustakaan untuk bekerja dengan SMTP dan, tentu saja, dari ORM atau perpustakaan untuk bekerja dengan Database, dll.
  2. Repository . . List Repository T[] ValueObject Entities. Repository InfrastructureService InfrastructureService Repository. : Logger, EmailSender.
  3. Repository InfrastructureService - EmailSender EmailService, FileService ( File.Open(… ) . .) .


Untuk memahami di mana harus meletakkan abstraksi, kita perlu memikirkan Ketergantungan Inversi dan Inversi Kontrol. Menurut mereka, ApplicationService kami dapat menggunakan Infrastruktur, saya tidak tahu apa implementasinya dengan cara seperti:
  1. Tentukan antarmuka yang akan mengimplementasikan Infrastruktur dan berinteraksi dengannya.
  2. Terima saja delegasi seperti Aksi dan Fungsi.


Melalui antarmuka:

    interface IRepository
    {
        int Get();
    }

    class ApplicationService
    {
        private readonly IRepository _repository;

        public ApplicationService(IRepository repository)
        {
            _repository = repository;
        }

        public int GetInt() => _repository.Get();
    }

Melalui delegasi:

    class ApplicationService
    {
        private readonly Func<int> _getIntFromDb;

        public ApplicationService(Func<int> getIntFromDb)
        {
            _getIntFromDb = getIntFromDb;
        }

        public int GetInt() => _getIntFromDb();
    }

Sekarang tentang cara menyusun kode. Ada dua hal yang perlu dipertimbangkan:
  1. Semuanya terbagi dalam beberapa folder.
  2. Semuanya dibagi menjadi beberapa perpustakaan.

Detail terminologi dapat ditemukan di sini .

Folder dalam aplikasi yang sama


Contoh Kode SnakeGame


Oleh perpustakaan


Kami menempatkan antarmuka InfrastructureServices (IRepository) di perpustakaan ApplicationServices, dan implementasinya (Repository) di perpustakaan Infrastructure.



Gambar terakhir dari sebuah artikel oleh seseorang dengan pengalaman pengembangan yang jauh lebih banyak daripada milik saya dan yang juga berpikir bahwa IRepository harus ditempatkan di Application Layer to ApplicationServices (implementasi Repositori sendiri juga memiliki Infrastruktur).


temuan


Antarmuka layanan infrastruktur (IRepository, IEmailSender) dapat ditempatkan di perpustakaan ApplicationServices.dll, dan implementasi spesifik mereka (Repositori, EMailSender) di perpustakaan Infrastructure.dll.

All Articles