وابستگی dependency
تزریق وابستگی به سبک google/wire: فراهمکنندههای نامدار، اتصال میانجی، پاکسازی و بررسی گراف برای وابستگی گمشده و چرخه.
واردسازی وابستگی
نام آرگومانها شناسهی خود کد است و معادل فارسی ندارد؛ گونهها، کلیدواژهها و نام بستهها با معادل فارسی نوشته میشوند.
وابستگی لایههای برنامه را به هم وصل میکند: یک مخزن، سرویسی که از آن استفاده میکند و کنترلکنندهای که از سرویس استفاده میکند. برای هر جزء یک فراهمکننده ثبت میکنید، نیازهایش را نام میبرید و بالای گراف را میخواهید. هر جزء یک بار ساخته میشود و بستن پاکسازیها را به ترتیب معکوس ساخت اجرا میکند.
سلام اطلاعات نوع در زمان اجرا ندارد، پس فراهمکنندهها با نامی که خودتان میگذارید، معمولاً نام نوع، شناخته میشوند. فراهمکننده تابعی است که ظرف را میگیرد و جزء را برمیگرداند و وابستگیهایش را با گرفتن میخواند. رشته دوم فراهم کردن همین وابستگیها را فهرست میکند تا ساختن گراف پیش از اجرا کل گراف را بررسی کند.
فراهمکنندهها و بررسی گراف
ساختن گراف رشته خالی برمیگرداند اگر گراف سالم باشد و در غیر این صورت پیامی که مشکل را نام میبرد: وابستگی گمشده، فراهمکننده تکراری یا چرخه وابستگی با مسیر کامل.
واردسازی وابستگی
ساختار Repo:
همگانی rows: صحیح = 0
پایان
ساختار Service:
همگانی repo: Repo = Repo {}
همگانی تابع Count(): صحیح:
برگشت این.repo.rows
پایان
پایان
ساختار Handler:
همگانی svc: Service = Service {}
همگانی تابع Serve(): رشته:
برگشت "rows=" + این.svc.Count()
پایان
پایان
تابع ریشه:
c := وابستگی.ساخت()
وابستگی.فراهم کردن(c، "Repo"، ""، Repo {}، (_c: وابستگی.ظرف): برگشت Repo { rows = 3 } پایان)
وابستگی.فراهم کردن(c، "Service"، "Repo"، Service {}، (cx: وابستگی.ظرف):
ناپایا r := Repo {}
_ok := وابستگی.گرفتن(cx، "Repo"، r)
برگشت Service { repo = r }
پایان)
وابستگی.فراهم کردن(c، "Handler"، "Service"، Handler {}، (cx: وابستگی.ظرف):
ناپایا s := Service {}
_ok := وابستگی.گرفتن(cx، "Service"، s)
برگشت Handler { svc = s }
پایان)
err := وابستگی.ساختن گراف(c)
اگر err نابرابر "":
سرچاپ err
برگشت 1
پایان
ناپایا h := Handler {}
_ok := وابستگی.گرفتن(c، "Handler"، h)
سرچاپ h.Serve()
وابستگی.بستن(c)
پایانگرفتن جزء را در صورت نبودن میسازد و در خروجی کپی میکند. اگر نام ناشناخته باشد یا در زمان اجرا به چرخه برسد نادرست برمیگرداند و خطا را پر میکند.
میانجی، مقدار و پاکسازی
پیوند نام یک میانجی را به فراهمکننده پیادهسازی آن وصل میکند. مقدار مقدار آمادهای مانند تنظیمات را ثبت میکند. هنگام بستن پاکسازی را به یک فراهمکننده میچسباند و بستن پاکسازی اجزای ساختهشده را از آخرین ساختهشده شروع میکند و ظرف را آزاد میکند.
خواندن خطاها
ساختن گراف فقط نامهای ثبتشده و فهرست نیازهایشان را نگاه میکند و هیچ کارخانهای را اجرا نمیکند. گراف سالم رشته خالی میدهد و سه پیام دیگر اینها هستند: missing dependency: Service needs Repo، duplicate provider: Repo و dependency cycle: A -> B -> C -> A. آن را یک بار هنگام شروع برنامه صدا بزنید و اگر متن خالی نبود همانجا بایستید. گرفتن با نامی که کسی ثبت نکرده نادرست برمیگرداند و missing provider: Nope را در خطا میگذارد.
واردسازی وابستگی
تابع report(label: رشته، c: وابستگی.ظرف):
msg := وابستگی.ساختن گراف(c)
سرچاپ label + ":"، msg == "" ? "sound" : msg
وابستگی.بستن(c)
پایان
تابع ریشه:
ok := وابستگی.ساخت()
وابستگی.فراهم کردن(ok، "Repo"، ""، 0، (_c: وابستگی.ظرف): برگشت 1 پایان)
report("fine"، ok)
missing := وابستگی.ساخت()
وابستگی.فراهم کردن(missing، "Service"، "Repo"، 0، (_c: وابستگی.ظرف): برگشت 1 پایان)
report("missing"، missing)
twice := وابستگی.ساخت()
وابستگی.فراهم کردن(twice، "Repo"، ""، 0، (_c: وابستگی.ظرف): برگشت 1 پایان)
وابستگی.فراهم کردن(twice، "Repo"، ""، 0، (_c: وابستگی.ظرف): برگشت 2 پایان)
report("duplicate"، twice)
loop := وابستگی.ساخت()
وابستگی.فراهم کردن(loop، "A"، "B"، 0، (_c: وابستگی.ظرف): برگشت 1 پایان)
وابستگی.فراهم کردن(loop، "B"، "C"، 0، (_c: وابستگی.ظرف): برگشت 2 پایان)
وابستگی.فراهم کردن(loop، "C"، "A"، 0، (_c: وابستگی.ظرف): برگشت 3 پایان)
report("cycle"، loop)
empty := وابستگی.ساخت()
ناپایا n := 0
سرچاپ "get:"، وابستگی.گرفتن(empty، "Nope"، n)، وابستگی.خطا(empty)
وابستگی.بستن(empty)
پایانانتخاب پیادهسازی در محل سیمکشی
انتخاب را در یک تابع که ظرف را میسازد نگه دارید. اینجا مقدار تنظیمات را نگه میدارد، دو فراهمکننده به دو روش یک Store میسازند و پیوند بسته به محیط نام Store را به یکی از آنها وصل میکند. کدی که Store میخواهد تغییری نمیکند. فقط اجزایی ساخته میشوند که کسی واقعاً خواسته است: از ۴ نام ثبتشده، ساخته شده در ظرف آزمایشی ۱ نام و در ظرف تولید ۲ نام را نشان میدهد.
واردسازی وابستگی
ساختار Config:
همگانی env: رشته = ""
پایان
ساختار Store:
همگانی kind: رشته = ""
پایان
تابع build(env: رشته): وابستگی.ظرف:
c := وابستگی.ساخت()
وابستگی.مقدار(c، "Config"، Config { env = env })
وابستگی.فراهم کردن(c، "Mem"، ""، Store {}، (_c: وابستگی.ظرف): برگشت Store { kind = "memory" } پایان)
وابستگی.فراهم کردن(c، "Disk"، "Config"، Store {}، (cx: وابستگی.ظرف):
ناپایا cfg := Config {}
_ok := وابستگی.گرفتن(cx، "Config"، cfg)
برگشت Store { kind = "disk for " + cfg.env }
پایان)
اگر env == "test":
وابستگی.پیوند(c، "Store"، "Mem")
وگرنه:
وابستگی.پیوند(c، "Store"، "Disk")
پایان
برگشت c
پایان
تابع ریشه:
for_env := ["test"، "prod"]
هر env در for_env:
c := build(env)
سرچاپ env + ":"، وابستگی.ساختن گراف(c) == "" ? "sound" : "broken"
ناپایا s := Store {}
_ok := وابستگی.گرفتن(c، "Store"، s)
سرچاپ " store is"، s.kind
built := وابستگی.ساخته شده(c)
سرچاپ " built"، built.طول()، "of"، وابستگی.تعداد(c)
built.آزادکن()
وابستگی.بستن(c)
پایان
پایانیک بار ساختن، به ترتیب معکوس بستن
هر فراهمکننده تکنمونه است: دو بار خواستن Cache کارخانهاش را یک بار اجرا میکند و از همان مقدار دو نسخه میدهد. پاکسازیهایی که با هنگام بستن ثبت شدهاند از آخرین جزء ساختهشده تا اولین اجرا میشوند، پس کش پیش از پایگاه دادهای که در دست دارد بسته میشود. بستن دوم کاری نمیکند.
واردسازی وابستگی
ناپایا made := 0
ساختار Db:
همگانی id: صحیح = 0
پایان
ساختار Cache:
همگانی db: Db = Db {}
پایان
تابع ریشه:
c := وابستگی.ساخت()
وابستگی.فراهم کردن(c، "Db"، ""، Db {}، (_c: وابستگی.ظرف):
made++
برگشت Db { id = 7 }
پایان)
وابستگی.فراهم کردن(c، "Cache"، "Db"، Cache {}، (cx: وابستگی.ظرف):
ناپایا d := Db {}
_ok := وابستگی.گرفتن(cx، "Db"، d)
برگشت Cache { db = d }
پایان)
وابستگی.هنگام بستن(c، "Db"، Db {}، (d: Db): سرچاپ "closing db"، d.id پایان)
وابستگی.هنگام بستن(c، "Cache"، Cache {}، (k: Cache): سرچاپ "closing cache over"، k.db.id پایان)
before := وابستگی.ساخته شده(c)
سرچاپ "before"، before.طول()
before.آزادکن()
ناپایا a := Cache {}
ناپایا b := Cache {}
_x := وابستگی.گرفتن(c، "Cache"، a)
_y := وابستگی.گرفتن(c، "Cache"، b)
سرچاپ "factory runs"، made
built := وابستگی.ساخته شده(c)
سرچاپ "order"، built.بگیر(0)، built.بگیر(1)
built.آزادکن()
وابستگی.بستن(c)
وابستگی.بستن(c)
سرچاپ "done"
پایانگونهها
ظرف Container
ساختار ظرف| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| وضعیت | st | State* | وضعیت مشترک ظرف. |
تابعها
ساخت New
تابع ساخت(): ظرفواردسازی وابستگی
تابع ریشه:
c := وابستگی.ساخت()
وابستگی.فراهم کردن(c، "Base"، ""، 0، (_c: وابستگی.ظرف): برگشت 10 پایان)
وابستگی.فراهم کردن(c، "Double"، "Base"، 0، (cx: وابستگی.ظرف):
ناپایا b := 0
_ok := وابستگی.گرفتن(cx، "Base"، b)
برگشت b * 2
پایان)
ناپایا d := 0
اگر وابستگی.گرفتن(c، "Double"، d):
سرچاپ d
پایان
وابستگی.بستن(c)
پایانفراهم کردن Provide
تابع فراهم کردن<T>(c: ظرف، name: رشته، needs: رشته، _witness: T، factory: تابع(ظرف): T)needs فهرستی از نام فراهمکنندههاست که با ویرگول جدا شدهاند، شاهد مقداری از گونه جزء است و فقط T را مشخص میکند و factory جزء را میسازد.نمونهی این مورد همراه با موارد بالاتر آمده است: dependency-Provide.salam
مقدار Value
تابع مقدار<T>(c: ظرف، name: رشته، v: T)واردسازی وابستگی
ساختار Config:
همگانی port: صحیح = 0
پایان
تابع ریشه:
c := وابستگی.ساخت()
وابستگی.مقدار(c، "Config"، Config { port = 8080 })
ناپایا cfg := Config {}
اگر وابستگی.گرفتن(c، "Config"، cfg):
سرچاپ cfg.port
پایان
وابستگی.بستن(c)
پایانپیوند Bind
تابع پیوند(c: ظرف، iface: رشته، concrete: رشته)iface را به فراهمکننده concrete وصل میکند.واردسازی وابستگی
میانجی Greeter:
تابع Hello(): رشته
پایان
ساختار English:
همگانی تابع Hello(): رشته:
برگشت "hello"
پایان
پایان
تابع ریشه:
c := وابستگی.ساخت()
وابستگی.فراهم کردن(c، "English"، ""، English {}، (_c: وابستگی.ظرف): برگشت English {} پایان)
وابستگی.پیوند(c، "Greeter"، "English")
ناپایا g := English {}
اگر وابستگی.گرفتن(c، "Greeter"، g):
سرچاپ g.Hello()
پایان
وابستگی.بستن(c)
پایانهنگام بستن OnClose
تابع هنگام بستن<T>(c: ظرف، name: رشته، _witness: T، f: تابع(T))بستن آن را صدا میزند.واردسازی وابستگی
ساختار Conn:
همگانی id: صحیح = 0
پایان
تابع ریشه:
c := وابستگی.ساخت()
وابستگی.فراهم کردن(c، "Conn"، ""، Conn {}، (_c: وابستگی.ظرف): برگشت Conn { id = 7 } پایان)
وابستگی.هنگام بستن(c، "Conn"، Conn {}، (v: Conn): سرچاپ "closing"، v.id پایان)
ناپایا x := Conn {}
_ok := وابستگی.گرفتن(c، "Conn"، x)
وابستگی.بستن(c)
پایانساختن گراف Build
تابع ساختن گراف(c: ظرف): رشتهواردسازی وابستگی
تابع ریشه:
c := وابستگی.ساخت()
وابستگی.فراهم کردن(c، "Service"، "Repo"، 0، (_c: وابستگی.ظرف): برگشت 1 پایان)
سرچاپ وابستگی.ساختن گراف(c)
وابستگی.فراهم کردن(c، "Repo"، "Service"، 0، (_c: وابستگی.ظرف): برگشت 2 پایان)
سرچاپ وابستگی.ساختن گراف(c)
وابستگی.بستن(c)
پایانگرفتن Get
تابع گرفتن<T>(c: ظرف، name: رشته، out &: T): منطقیout کپی میکند. اگر نام ناشناخته باشد یا به چرخه برسد نادرست برمیگرداند و خطا را پر میکند.نمونهی این مورد همراه با موارد بالاتر آمده است: dependency-Provide.salam
خطا Error
تابع خطا(c: ظرف): رشتهتعداد Count
تابع تعداد(c: ظرف): صحیحساخته شده Built
تابع ساخته شده(c: ظرف): وکتور<رشته>بستن Close
تابع بستن(c: ظرف)نمونهی این مورد همراه با موارد بالاتر آمده است: dependency-OnClose.salam