Method Injection — dependency’ni class constructori yoki property’si orqali doimiy saqlash o‘rniga, aynan kerakli method chaqirig‘ida argument sifatida berish usuli. U Dependency Injectionning bir ko‘rinishi hisoblanadi.
Method Injection dependency faqat bitta operation uchun kerak bo‘lsa yoki har chaqiriqda boshqa implementation berilishi kerak bo‘lsa foydali.
Asosiy ko‘rinish
Misol:
class ReportService:
def generate(self, data, formatter):
return formatter.format(data)
formatter service state’ida saqlanmaydi.
Har chaqiriqda boshqa formatter berish mumkin:
PDF formatter
CSV formatter
HTML formatter
Constructor Injection bilan farqi
Constructor Injection dependency classning deyarli barcha operationlari uchun required ekanini bildiradi.
OrderService(repository)
Method Injection esa dependency faqat ma’lum methodga kerakligini ko‘rsatadi.
export(order_id, exporter)
Required va uzoq muddatli dependency constructor orqali berilgani aniqroq.
Call-site dependency
Method signature dependency’ni call site’da ko‘rsatadi.
Caller qaysi implementation ishlatilishini tanlaydi.
Bu behaviorni runtime’da har operation bo‘yicha almashtirishga yordam beradi.
Kamchiligi — caller dependency yaratish yoki olishni bilishi kerak.
Strategy bilan aloqa
Method orqali berilgan dependency ko‘pincha Strategy Pattern vazifasini bajaradi.
Masalan:
sort(items, comparison_strategy)
Har call boshqa strategy oladi.
Strategy object state’siz va kichik bo‘lsa function yoki callback ham yetarli bo‘lishi mumkin.
Callback injection
Dependency to‘liq interface emas, callback sifatida beriladi.
process(items, on_error=handler)
Bu kichik extension point uchun qulay.
Callback signature murakkablashsa alohida protocol yoki class aniqroq.
Context injection
Method operationga tegishli context qabul qiladi.
Masalan:
- current user;
- transaction;
- cancellation token;
- request ID;
- clock;
- locale.
Bularning hammasi business parameter va technical dependency o‘rtasida farqlanadi.
Juda katta context object Service Locatorga aylanmasligi kerak.
Transaction berish
Methodga transaction yoki unit of work berilishi mumkin.
save(entity, transaction)
Bu bir nechta service operationini bitta transactionga birlashtirish imkonini beradi.
Ammo barcha qatlamlarga transaction obyektini uzatish persistence detalini domain ichiga olib kirishi mumkin.
Cancellation token
Uzoq operationga cancellation signal method argumenti orqali beriladi.
Method tokenni:
orasida tekshiradi.
Bu per-call dependency bo‘lgani uchun constructor state’iga mos emas.
Clock injection
Current timega bog‘liq methodga clock berish mumkin.
expire_subscription(subscription, clock)
Testda fixed clock ishlatiladi.
Agar classdagi ko‘p method vaqtga tayanadigan bo‘lsa constructor injection qulayroq.
Optional dependency
Method optional collaborator qabul qilishi mumkin.
Masalan:
generate(report, progress_listener=None)
Optional behavior default no-op implementation bilan soddalashtirilishi mumkin.
Ko‘p nullable dependency branchlarni oshiradi.
Interface Injection bilan farqi
Interface Injection’da class maxsus injection methodini amalga oshirishi mumkin:
set_logger(logger)
Method Injection esa business operation methodining argumenti sifatida dependency beradi.
Atamalar ayrim manbalarda turlicha ishlatilishi mumkin.
Property Injection bilan farqi
Property Injection dependency obyekt yaratilgandan keyin fieldga beriladi.
Bu required dependency’ni vaqtincha bo‘sh qoldirishi mumkin.
Method Injectionda dependency callning o‘zida required bo‘lib, operation boshlanishidan oldin mavjud.
Test
Method Injection testda fake yoki spy’ni bevosita argument sifatida uzatadi.
service.generate(data, FakeFormatter)
Container yoki global patch kerak emas.
Chaqiriqlar soni va argumentlar spy orqali tekshiriladi.
Stateless service
Method Injection service’ni stateless saqlashga yordam beradi.
Har requestga tegishli dependency call argumentida keladi.
Bunday service singleton sifatida xavfsizroq bo‘lishi mumkin, agar ichki mutable state bo‘lmasa.
Signature hajmi
Juda ko‘p method dependencylari signature’ni uzun qiladi.
Masalan:
execute(command, repository, clock, logger, tracer, validator, notifier)
Bu class responsibility juda katta ekanini ko‘rsatishi mumkin.
Dependencylarni cohesive service yoki constructor orqali guruhlash kerak.
Dependency propagation
Method Injection dependency’ni yuqori qatlamdan ko‘p ichki methodlarga uzatishga olib kelishi mumkin.
Bu parameter threading.
Agar dependency butun use case davomida kerak bo‘lsa request context yoki constructor scope qulayroq bo‘lishi mumkin.
Hidden dependency
Method ichida global container’dan dependency olish yashirin dependency hisoblanadi.
Method Injection aksincha dependency’ni signature’da ko‘rsatadi.
Bu code contractini aniq qiladi.
Framework method injection
Ba’zi frameworklar controller method parameterlarini avtomatik resolve qiladi.
Masalan:
Bu qulay, ammo methodni frameworkdan tashqarida chaqirish uchun dependencylarni qo‘lda berish kerak.
Qachon ishlatiladi
Method Injection quyidagi holatlarda mos:
- dependency faqat bitta methodga kerak;
- har call boshqa strategy ishlatadi;
- callback;
- cancellation;
- per-request context;
- test uchun vaqt yoki random manbasi;
- operation-specific transaction.
Kamchiliklari
Caller murakkablashishi mumkin.
Dependency ko‘p qatlamlar bo‘ylab uzatiladi.
Method signature business data va technical collaboratorlar bilan aralashib ketishi mumkin.
Noto‘g‘ri ishlatilsa class interface’i beqaror bo‘ladi.
Method overload
Bir xil operationning dependencyli va default dependencyli variantlari bo‘lishi mumkin.
Default method production implementationni chaqiradi, explicit variant test yoki maxsus workflow uchun.
Ko‘p overload interface’ni noaniq qilishi mumkin.
Pure functionga yaqinlashish
Dependency va inputlarning barchasi method argumentida bo‘lsa operation yashirin global state’dan kamroq foydalanadi.
Bu deterministic test va parallel executionni osonlashtiradi.
Ammo database yoki logger kabi doimiy collaboratorlarni har chaqiriqda uzatish ortiqcha shovqin bo‘lishi mumkin.
Bog‘liq tushunchalar
Dependency Injection, Constructor Injection, Property Injection, Strategy Pattern, Callback, Cancellation token, Clock, IoC, Stateless service, Parameter threading