تزریق wire
تزریق وابستگی به سبک 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 += 1
برگشت 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 جزء را میسازد.نمونهی این مورد همراه با موارد بالاتر آمده است: wire-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 کپی میکند. اگر نام ناشناخته باشد یا به چرخه برسد نادرست برمیگرداند و خطا را پر میکند.نمونهی این مورد همراه با موارد بالاتر آمده است: wire-Provide.salam
خطا Error
تابع خطا(c: ظرف): رشتهتعداد Count
تابع تعداد(c: ظرف): صحیحساخته شده Built
تابع ساخته شده(c: ظرف): وکتور<رشته>بستن Close
تابع بستن(c: ظرف)نمونهی این مورد همراه با موارد بالاتر آمده است: wire-OnClose.salam