Ko'proq

STAThread-ni ESRI qo'shimchasiga qo'shish

STAThread-ni ESRI qo'shimchasiga qo'shish


Hozir men biroz tiqilib qoldim, menda usullarning bir qismi sifatida SavefileDialog ob'ektini o'z ichiga olgan c # addin bor. Kodda Taymer ham mavjud. Foydalanuvchi uchun qadamlar:

  • Xaritani bosing
  • Geometriya chizilgan
  • Xarita yangilandi
  • Taymer 5 soniya o'tishini kutadi (xaritani yangilash uchun etarli vaqt)
  • Foydalanuvchiga savol beradigan dialog oynasi paydo bo'ladi
  • Agar ular ha ni tanlasalar, SaveFileDialog ob'ekti paydo bo'ladi.

SaveFileDialog paydo bo'lishidan oldin men quyidagi xatoga yo'l qo'yganman

OLE qo'ng'iroqlarini amalga oshirishdan oldin joriy oqim bitta yo'nalishli kvartira (STA) rejimiga o'rnatilishi kerak. Asosiy funktsiyangizda STAThreadAttribute belgisi o'rnatilganligiga ishonch hosil qiling.

Mening kodimga qayerda [STAThread] atributini qo'yaman, chunki menda asosiy funktsiya yo'q. Addin - bu asboblar paneli va bitta tugma.


Taymerni ishlatish o'rniga (alohida ish zarrachasida ishlaydi) ichki hodisalarni qanday ishlatish kerak: IActiveViewEvents.ViewRefreshed (yangilanishni boshlash) va keyin IActiveViewEvents.AfterDraw (tugagan yangilash). Agar siz AfterDraw-ni chizilgan maydon bilan tinglasangizesriViewDrawPhase.esriViewForegroundyokiesriViewDrawPhase.esriViewAll(sizga nima mos kelishini ko'rish uchun biroz tajriba qilishingiz kerak bo'lishi mumkin), keyin qancha vaqt ketmasin, xarita yangilanganidan keyin voqea boshlanadi.

"Men bu yangilanishni chaqirdim" degan mantiqiy (global miqyosda) bo'ling, yoki ko'rinish yangilanganida saqlash oynasi paydo bo'ladi:

// global bool pIveCalledThisRefresh = false; // formada xususiy void Form1_Load yuklanadi (ob'ekt yuboruvchisi, EventArgs e) {IApplication m_application = ArcMap.Application; IMxDocument gDoc = (IMxDocument) m_application.Document; IScreenDisplay gScreenDis = gDoc.ActiveView.ScreenDisplay; ((IActiveViewEvents_Event) gDoc.FocusMap) .AfterDraw + = yangi IActiveViewEvents_AfterDrawEventHandler (My_AfterDraw); } // tugmachasida voqea shaxsiy bo'shligi Go_Click (ob'ekt yuboruvchisi, EventArgs e) {pIveCalledThisRefresh = true; // ba'zi narsalar qiling va xaritani yangilang pIveCalledThisRefresh = false; // normal holatga qaytish} // voqeadan so'ng void My_AfterDraw (IDisplay Display, esriViewDrawPhase phase) {if (! pIveCalledThisRefresh) return; // agar siz ularga (faza == esriViewDrawPhase.esriViewForeground) sabab bo'lmasangiz, yangilanishlarni o'tkazib yuboring // bu bilan tajriba o'tkazing, qanday bosqichni xohlayotganingizni ko'ring {if (MyDialog.ShowDialog () == System.Windows.Forms.DialogResult.OK) {// tejashingiz mumkin}}}

Agar yangilangan tugagandan keyin hali ham kutishni istasangiz, DateTime ob'ekti sifatida vaqtni oling, bir necha soniya qo'shing va keyin DateTime.Compare () bilan solishtiringDoEvents ()pastadirda:

void My_AfterDraw (IDisplay Display, esriViewDrawPhase phase) {if (! pIveCalledThisRefresh) return; // agar siz ularga sabab bo'lmasangiz yangilanishlarni o'tkazib yuboring, agar (phase == esriViewDrawPhase.esriViewForeground) // bu bilan tajriba o'tkazsangiz, qaysi bosqichni xohlayotganingizni ko'ring {pSaveTime = DateTime.Now; pSaveTime.AddSeconds (5.0); // o'zboshimchalik bilan 5 soniya qiladi {// hech narsa yo'qligi System.Windows.Forms.Application.DoEvents (); // boshqa jarayonlarga o'z ishlarini bajarishga imkon beradi} while (DateTime.Compare (pSaveTime, DateTime.Now)> 0); agar (MyDialog.ShowDialog () == System.Windows.Forms.DialogResult.OK) {// o'zingizni tejashingiz kerak}}}

Bularning barchasi bir xil ipda ishlaydi, bu sizning Esri ob'ektlarini kesib o'tish iplarini engillashtiradi, bunga yo'l qo'yilmaydi, chunki barcha Esri ob'ektlari xavfsiz emas.


Agar siz System.Timers.Timer yoki System.Threading.Timer dan foydalanayotgan bo'lsangiz, taymer tomonidan ishga tushiriladigan kodingiz ishchi oqimida paydo bo'ladi. Ushbu mavzu STAThread bilan belgilanmaydi va shuning uchun SaveFileDialog-dan foydalanib bo'lmaydi.

Siz sinxron va asosiy interfeys satrida bo'lgan System.Windows.Forms.Timer-dan foydalanishingiz mumkin yoki Control.Invoke-dan foydalanib kodingizni asosiy ish zarrachasida ishlatishingiz mumkin (yoki WinForms o'rniga WPF dan foydalansangiz IDispatcher.Invoke).


STAThreadAttribute qo'llanilganda, u joriy ipning kvartira holatini bitta ipli qilib o'zgartiradi. MAQOMOTI va ish zarrachalari haqida juda katta munozaraga kirishmasdan, bu atribut hozirgi ip va u bilan MAQOMOTI orqali suhbatlashishni istashi mumkin bo'lgan boshqa iplar o'rtasidagi aloqa mexanizmini ta'minlaydi. Windows Forms-dan foydalanayotganingizda, foydalanayotgan xususiyatingizga qarab, operatsion tizim komponentlari bilan aloqa o'rnatish uchun COM interop-dan foydalanishi mumkin. Bunga yaxshi misollar - Bufer va Fayl dialoglari.

Boshqa yo'l bilan aytganda, bufer operatsion tizimining komponentlari bilan aloqa MAQOMOTI orqali amalga oshiriladi va bu STA ipidan foydalangan holda ipning kvartira holatini o'zgartirishni talab qiladi.


STAThread atributi MAQOMOTI uchun dastur bitta ipli kvartiradan (STA) foydalanishi kerakligini ko'rsatish uchun ishlatiladi. Bu faqat MAQOMOTI ob'ektlariga ta'sir qiladiva faqat MAQOMOTI (FileOpenDialog kabi) dan foydalanadigan ba'zi dialog oynalari to'g'ri ish zarrachalar modelini ko'rsatishi kerakligi sababli talab qilinadi.

Mening bilishimcha, Windows Forms dialoglari bundan mustasno, juda kam (agar mavjud bo'lsa) o'yinni rivojlantirish COM-dan foydalanadi va shuning uchun bu hech qanday ta'sir qilmaydi, shunchaki ushbu dialog oynalari uchun talab qilinadi.

Agar siz MAQOMOTI ob'ektlaridan foydalansangiz, unda siz mumkin ushbu sozlamaning ma'nosini to'liq tushunish uchun MAQOMOTI ish zarrachalari modellarini ko'rib chiqishni xohlaysiz, ammo qisqa versiyasi shundaki, STA-da barcha MAQOMOTI usullari boshqa birida chaqirilgan bo'lsa ham, bitta satrda ishlaydi (bu holda UI ipi). ip.

Yangilash: DirectX MAQOMOTI ob'ektlari to'plami sifatida mavjud, ammo ular qanday ish zarrachasini talab qilishiga amin emasman.


  1. Sizda hamma foydalanuvchi tomonidan o'rnatilishi mumkin bo'lgan UserName statik mulki mavjud. Siz ushbu mulkdan foydalanishni batafsil bayon qilmadingiz.

Agar uni yangilash kerak bo'lgan kirish shakli bo'lsa va u hech qachon yangilanmasa, dastur maydoniga ushbu maydonni o'rnating.

Agar bu maydonni yangilaydigan boshqa sinf bo'lsa, ehtimol bu xususiyat bu erga tegishli emas.

Sizda takrorlangan bir nechta kod bor, shuning uchun yaxshiroq qilish uchun usul bo'lishi kerak.

Mening fikrimcha, siz o'zingizning asosiy usulingizda juda ko'p turli xil ishlarni qilyapsiz, ehtimol siz ushbu operatsiyalarni alohida usullarga kiritishingiz mumkin: Init, Login, Start.

Siz MainForm uchun Taqdimotchini Tag xususiyatiga qo'ydingiz, bu menimcha ma'lum bir xususiyatga tegishli. Shu tarzda MainForm unga kimning kirish huquqini boshqarishi mumkin, aks holda MainForm-ga kirish huquqiga ega bo'lgan har qanday ob'ekt Tag va shuning uchun Taqdimotchini tiklay oladi. Yana bir muammo shundaki, Tag xususiyati ob'ektdir, shuning uchun uni har safar ishlatmoqchi bo'lganingizda o'zgartirishingiz kerak bo'ladi.


1 javob 1

Men Hududlardan foydalanishga qat'iy qarshi emasman, lekin ulardan foydalanishga qarshiman ichida usullari. Men buni aniq kod hidi deb bilaman. Usullar ichidagi hududlarni o'z uslubiga ajratish va ularni chaqirish kerak. Masalan

Endi, agar ushbu narsalardan birortasi qanday o'rnatilishini o'zgartirish kerak bo'lsa, siz izlayotgan sozlash qismi uchun yuzlab kod satrlarini qidirish o'rniga to'g'ridan-to'g'ri ushbu usulga o'tishingiz mumkin.

Xop. Keling, buni qisqartirishimga ijozat bering. Ekstrakt usullari. Ekstrakt usullari hamma joyda. Sizning keyboardHook_KeyDown usuli 59 qatordan iborat. Men aylantirishim kerak bir nechta butun usulni ko'rish uchun marta. Biz insonmiz, birdaniga boshimizga buncha narsani tuta olmaymiz. Ekstraksiya usullari bizning kodimizdan takrorlashni olib tashlash uchungina emas. Bu usullarni alohida mas'uliyatli va bir qarashda tushunadigan darajada kichik qilish uchun. Agar biz tafsilotni xohlasak, biz kichikroq usullarga sho'ng'iymiz. Aks holda, biz tafsilotlar bilan bog'liq bo'lmagan holda, sodir bo'layotgan voqealarni tezda ko'rib chiqamiz.

Sizning sozlamalaringiz klassi bu borada ancha yaxshi, ammo u bilan bog'liq boshqa muammolar mavjud.

  • Barcha usullar statikdir, shuning uchun siz sinfning o'zini statik qilib qo'yishingiz mumkin. Hech qachon bunday holatlarga ega bo'lishning ma'nosi yo'q, davlat yo'q.
  • Ehtimol, Windows Ro'yxatdan o'tish kitobi orqali XML konfiguratsiyasidan foydalanish afzaldir. Iltimos, C # .Net-da App.config nima ekanligini va uni qanday ishlatishim kerakligini ko'rib chiqing. Biroq, ro'yxatga olish kitobidan foydalanishda hech qanday yomon narsa yo'q. Buni afzal ko'rgan narsa deb hisoblash mumkin.

Agar siz reestrga rioya qilishga qaror qilsangiz, kalitlarni ro'yxatdan o'tkazadigan joyni o'zgartirishingiz kerak.

Dasturiy ta'minot ostidagi boshqa tugmachalarni ko'rib chiqing. Ularning barchasi (aksariyati) qanday qilib Company NameOfSoftware shaklida bo'lishiga e'tibor bering. Siz ushbu anjumanga rioya qilishingiz kerak. Bu sizning boshqa biron bir dasturiy ta'minot bilan "nom maydoni" ziddiyatiga duch kelish ehtimolini cheksiz kamaytiradi. Ushbu dastur ochiq kodli dastur bo'lgani uchun github foydalanuvchi nomingizdan foydalanishni tavsiya etaman.


ISpatialReferenceFactory3 interfeysi

Vertikal ma'lumotlar bazalarini yoki koordinatali tizimlarni yaratadigan a'zolarga kirishni ta'minlaydi.

Mahsulot mavjudligi

Qachon foydalanish kerak

ISpatialReferenceFactory3 vertikal koordinatali tizimni qo'llab-quvvatlash va mavjud bo'lgan past aniqlikdagi fazoviy ma'lumotnomalarni yuqori aniqlikdagi fazoviy ma'lumotnomaga (yoki aksincha) aylantirish usullarini taqdim etadi.

A'zolar

Tavsif
ConstructHighPrecisionSpatialReference Mavjud fazoviy ma'lumotnoma asosida yuqori aniqlikdagi fazoviy ma'lumotnomani tuzadi. xy / z / mDoubler - tegishli aniqlikni necha marta oshirish kerakligi. Nol qiymati bu aniqlik uchun maksimal ikki baravar ko'payishini topadi.
ConstructLowPrecisionSpatialReference Yuqori aniqlikdagi kirish koeffitsienti bilan bir xil o'lchov faktori bilan, ammo boshqa domen darajasida past aniqlikdagi makon ma'lumotnomasini tuzing. Agar hisoblangan domen darajasi ko'rsatilgan ma'lumotlarni qamrab ololmasa, xato qaytariladi.
CreateDatum Oldindan belgilangan ma'lumotlar bazasini yaratadi.
CreateESRISpatialReference-ni yarating Fazoviy ma'lumotnoma tizimini yaratadi va uni belgilangan ESRISpatialReference buferidan belgilaydi.
CreateESRISpatialReferenceFromPRJ-ni yarating PRJ satridan fazoviy ma'lumotnoma yaratadi.
CreateESRISpatialReferenceFromPRJFile PRJ faylidan fazoviy ma'lumotnoma yaratadi.
CreateESRISpatialReferenceInfo Fazoviy ma'lumotnoma tizimini yaratadi va uni belgilangan ESRISpatialReference buferidan belgilaydi.
CreateESRISpatialReferenceInfoFromPRJ PRJ satridan fazoviy ma'lumotnoma yaratadi.
CreateESRISpatialReferenceInfoFromPRJFile PRJ faylidan fazoviy ma'lumotnoma yaratadi.
CreateGeographicCoordinateSystem Oldindan belgilangan geografik koordinatalar tizimini yaratadi.
CreateGeoTransformation Geografik koordinatalar tizimlari o'rtasida oldindan belgilangan o'zgarishni yaratadi.
CreateParameter Oldindan belgilangan parametrni yaratadi.
CreatePredefinedAngularUnits Oldindan belgilangan burchakli birliklar ro'yxatini tuzadi.
CreatePredefinedDatums Oldindan belgilangan ma'lumotlar bazalari ro'yxati ro'yxatini tuzadi.
CreatePredefinedGeographicTransformations Oldindan belgilangan geografik transformatsiyalar ro'yxatini tuzadi.
CreatePredefinedLinearUnits Oldindan belgilangan chiziqli birliklar ro'yxatini tuzadi.
CreatePredefinedPrimeMeridians Oldindan belgilangan asosiy meridianlar ro'yxatini tuzadi.
CreatePredefinedProjections Oldindan belgilangan proektsiyalar ro'yxatini tuzadi.
CreatePredefinedSpheroids Oldindan belgilangan sferoidlar ro'yxatini tuzadi.
CreatePredefinedVerticalCoordinateSystems Oldindan belgilangan vertikal koordinatali tizimlarning ro'yxatini yaratadi.
CreatePredefinedVerticalDatums Oldindan belgilangan vertikal ma'lumotlar bazalarining ro'yxatini yaratadi.
CreatePrimeMeridian Oldindan belgilangan asosiy meridianni yaratadi.
CreateProjectedCoordinateSystem Oldindan belgilangan prognozlangan koordinatalar tizimini yaratadi.
CreateProjection Oldindan belgilangan proektsiyani yaratadi.
CreateSpatialReference-ni yarating SrID-dan oldindan aniqlangan fazoviy ma'lumotnoma yaratadi.
CreateSpheroid Oldindan belgilangan sferoidni yaratadi.
CreateUnit Oldindan belgilangan o'lchov birligini yaratadi.
CreateVerticalCoordinateSystem Ro'yxat yoki ID kodidan oldindan belgilangan vertikal koordinatalar tizimini yaratadi.
CreateVerticalCoordinateSystemFromESRISpatialReference-ni yarating Uning satr formatidan vertikal koordinatalar tizimini yaratadi.
CreateVerticalDatum Ro'yxat yoki ID kodidan oldindan belgilangan vertikal ma'lumotlar bazasini yaratadi.
ExportESRISpatialReferenceInfoToPRJFile PRJ fayliga fazoviy ma'lumotni eksport qiladi.
ExportESRISpatialReferenceToPRJFile PRJ fayliga fazoviy ma'lumotni eksport qiladi.
GeoTransformationDefault Standart geografik o'zgarishlarning ro'yxatini qaytaradi.
GetPredefinedGeographicTransformations Oldindan belgilangan geografik transformatsiyalar ro'yxatini qaytaradi.

Irsiy interfeyslar

Interfeyslar Tavsif
ISpatialReferenceFactory2 Turli xil fazoviy ma'lumot komponentlarini yaratadigan a'zolarga kirishni ta'minlaydi.
ISpatialReferenceFactory Turli xil fazoviy ma'lumot komponentlarini yaratadigan a'zolarga kirishni ta'minlaydi.

ISpatialReferenceFactory-ni amalga oshiradigan CoClasses3

Izohlar

The ISpatialReferenceFactory3 interfeysida past va yuqori aniqlikdagi fazoviy ma'lumotnomalar bilan ishlashda foydali bo'lgan ikkita usul mavjud. ConstructHighPrecisionSpatialReference past aniqlikdagi fazoviy ma'lumotnomadan yuqori aniqlikdagi fazoviy ma'lumotnoma hosil qiladi. Ushbu usuldan foydalanish koordinatali qiymatlarning yangi, zichroq to'rga to'liq mos kelishini ta'minlaydi. Dastlabki panjaraning har bir kesishmasi yangi panjaraning kesishmasidir. ConstructLowPrecisionSpatialReference mavjud bo'lgan yuqori aniqlikdan past aniqlikdagi kosmik ma'lumotni yaratadi. Siz odatda XY domeni hisobiga yangi rezolyutsiya qiymatini saqlab turishni talab qilishingiz mumkin.

Ushbu interfeysni konsol dasturida ishlatganda, siz muntazam ravishda bitta ipli deb belgilashingiz kerak. Sinf sizning odatiy deklaratsiyangizdan oldin [STAThread] atributini qo'shish orqali bitta yo'nalishli deb belgilanishi mumkin.

[STAThread]
statik bo'sh joy Asosiy (string [] args)
<
>

Ushbu interfeysni konsol dasturida ishlatganda, siz muntazam ravishda bitta ipli deb belgilashingiz kerak. Sinf sizning odatiy deklaratsiyangizdan oldin [STAThread] atributini qo'shish orqali bitta yo'nalishli deb belgilanishi mumkin.


NInject yordamida zavod qurishning eng yaxshi usuli qanday?

MVC3 da NInject yordamida qaramlik in'ektsiyasi bilan men juda qulayman. MVC3 dasturida ishlayotganda men NInject-dan foydalangan holda maxsus Controller Creation Factory ishlab chiqardim, shuning uchun har qanday yaratilgan kontroller ushbu Controller Factory orqali unga bog'liqliklarga ega bo'ladi.

Endi men Windows dasturini ishlab chiqishni boshlayman, Ilovadan keng bog'liqlik in'ektsiyasidan foydalanmoqchiman. ya'ni har qanday ob'ekt NInject orqali yaratilishi kerak, shunda birlik sinovini engillashtiradi. Iltimos, yaratilgan har bir ob'ekt faqat NInject Factory-da bo'lishi kerakligini ta'minlash uchun menga rahbarlik qiling.

Masalan, agar biron-bir derazada Button_Click hodisasida men yozsam:

va TestClass, masalan, ITestga bog'liqdir, keyin u avtomatik ravishda hal qilinishi kerak. Men foydalanishim mumkinligini bilaman:

Lekin har safar ob'ekt yaratmoqchi bo'lganimda buni qilish menga zerikarli tuyuladi. Shuningdek, u ishlab chiquvchini ob'ektni ma'lum bir tarzda yaratishga majbur qiladi. Buni yaxshiroq qilish mumkinmi?

Ob'ekt yaratish uchun markaziy omborga ega bo'lsam bo'ladimi, keyin har bir ob'ekt yaratilishi ushbu ombordan avtomatik ravishda foydalanadimi?


Siz manifest faylini yaratishingiz va dasturni ma'muriy imtiyozlarni talab qiladigan qilib sozlashingiz mumkin. Ilovangiz ishga tushirilganda, bu sizdan hech qanday kod talab qilmasdan, UAC foydalanuvchisi so'rovi xiralashgan ekran bilan boshlanadi.

Gory tafsilotlari uchun MSDN-ga qarang:

Ushbu faylni istalgan matn muharriri yordamida yaratish mumkin. Ilova manifest faylida .manifest kengaytmasi bilan maqsadli bajariladigan fayl bilan bir xil nom bo'lishi kerak.

Sizning kodingizni aniqroq qilish yoki standartlarga mos kelish uchun o'zgartiradigan ikkita narsa bor.

Ushbu usul nomini RunningAsAdmin-ga o'zgartirgan bo'lar edim va o'zgaruvchan printsip CamelCasing o'zgaruvchilari uchun standart nomlash sxemasiga mos keladigan kichik harflar bilan yozilishi kerak.

shuningdek if usulini tuzishni asosiy usulda o'zgartirgan bo'lardim.

mantiqiy usulni inkor etish o'rniga men uni o'ynashiga yo'l qo'yar edim, siz baribir uni biron bir tarzda tekshirasiz, shuning uchun inkor shunchaki noto'g'ri ko'rinadi

Mantiqiylikni qaytarish uchun bizga Elevate kerakmi? Men ko'rgan narsadan u aslida haqiqiy / noto'g'ri qiymat bilan hech narsa qilmaydi.

Keling, uni bekor qilish usuliga aylantiraylik va u buni amalga oshirsin va u erga etib boraylik, hech qanday qaytarma bayonoti yo'q.


. executable.exe pasta -a - million "argument"

Buyruqning o'zgarishi: joylashtirish | buyruq

Belgilangan buyruq buyrug'ining kiritilishiga Windows Clipboard-ning tarkibini joylashtiring.

joylashtirish | buyruq | klip

Belgilangan buyruq buyrug'ining kiritilishiga Windows Clipboard-ning tarkibini joylashtiring, so'ngra uning natijasini Windows Clipboard-ga nusxalash.

Masalan, joylashtirish | saralash | clip Windows Clipboard-ning tarkibini saralaydi. Talab qilinadi: klip

joylashtirish> fayl nomi

paste> example.txt

Belgilangan fayl nomi fayliga Windows Clipboard-ning tarkibini joylashtiradi.

joylashtirish | tartiblash> fayl nomi

Windows Clipboard-ning tarkibini saralash va saralangan chiqishni belgilangan fayl nomi faylida saqlash.


1 javob 1

Men tushunganimdek, dastur kompozitsion ildiz oddiygina bu erda kompozitsiya sodir bo'ladi - kirish nuqtasiga iloji boricha yaqinroq. Bu sinf "kompozitsiya ildizi" ni o'z ichiga olmaydi, shunchaki IKernel-ni o'raladi va oxir-oqibat haqiqiy kompozitsiya ildizini Ninject taqdim etadigan barcha moslashuvchanlik va quvvatdan mahrum qiladi. Bitta to'g'ri yo'l yadroga kirish.

Gap shundaki, bu sinfning mavjudligi shunchaki a ko'taradi Katta qizil bayroq: chunki u mavjudva tipik (statik) yadro nusxasini saqlaganligi sababli, ushbu kod satrini loyihaning istalgan joyida bo'lish juda oson:

. va sizda buni ApplicationShellController sinfida bor - va siz statik usullarga duch kelganingiz uchun siz ham shart emassiz uni qaramlik sifatida o'tkazib yuboring . lekin bu a xizmatni aniqlash shunga qaramay, chunki ApplicationShellController-da a qaramlik CompositionRoot turida - ya'ni ildiz endi ildizda emas!

LINQ biti kerak bo'lgandan ko'ra murakkabroq ko'rinadi. ResolveAll & ltT & gt IEnumerable & ltT & gt-ni qaytaradi, shuning uchun Cast & ltT & gt ortiqcha. Keyin Select emas loyihalash har qanday narsa va qaerda FirstOrDefault uchun asos bo'lishi mumkin:

Agar niyat qaytib kelmoqchi bo'lsa bitta nazoratchi bo'lsa-da, va niyati shundaki, u erda hech qachon bo'lmaydi bitta berilgan yo'lni boshqarish uchun kontroller, undan keyin niyatni aniqroq qilish uchun .FirstOrDefault o'rniga .SingleOrDefault-dan foydalanishingiz kerak (va agar bu yo'l uchun qaytish o'rniga yaxshi ikkita yoki undan ortiq kontroller mavjud bo'lsa, usul istisno qiladi). narsa sizga berishni xohlagan har qanday turdagi tasodifiy tekshirgich).

Agar men sizning arxitekturangizni to'g'ri tushunsam, ushbu usul har safar chaqirilganda, sizga tekshiruvchining yangi nusxasi kerak emas.

Ammo siz aynan shu narsani olasiz.

ApplicationShellController konstruktori shunday ko'rinishi kerak deb o'ylayman:

Ninject IEnumerable & ltIDocumentController & gt qaramligini ko'p bog'lash uchun imkoniyat deb biladi: u avtomatik ravishda IDocumentController-ga bog'langan har bir narsaning nusxasini hal qiladi va uni uzatadi.

Bu erda sizga [Inject] atributi kerak emas. [Inject] atributlaridan foydalanmang. O'zingizning kompozitsiyangiz ildizini butunlay boshqacha assambleyada tasavvur qiling - bu sizning echimingizdagi yagona yig'ilish ehtiyojlar Ninject-ga havola, bu kompozitsion ildizga ega bo'lgan yig'ilishdir. Ninject-ga boshqa joyda qaramlikni taqiqlash kerak, sizning kodingiz to'liq IoC Container-agnostik usulda yozilishi kerak: sizning biznes kodingizda [Inject] atributi bo'lishi sizning biznes kodingiz istalgan vaqtda IKernel bilan ishlashga qodirligini anglatadi. vaqt, va siz bunday taassurot qoldirishni xohlamaysiz - faqat vaqt o'tishi bilan kod saqlanib qolishi sababli bo'lsin yana kimdir (ha, kelajak sizni boshqasi!), va bunga aniq xabar yuborish har doim yaxshi kelajakda xizmat ko'rsatuvchi, IoC konteyner o'zining kichik burchagida yashaydi va o'ladi va hech qayerga bormaydi.

Albatta istisnolar mavjud. Masalan, siz Ninject.Logging kengaytmasidan foydalanishni xohlaysiz va har qanday log-yoqilgan turga ILogger-ni konstruktor-AOK qiling.

Shunday qilib, men CompositionRoot sinfini olib tashladim va IKernel-ni to'g'ridan-to'g'ri kirish nuqtasiga o'tkazdim konvensiyalar kengaytmasi va shunga o'xshash narsalarni bajaring:

Konventsiyalar kengaytmasi bitta yo'riqnomada barcha interfeyslarni avtomatik ravishda bog'lab qo'yishdan ko'ra ko'proq narsani amalga oshirishi mumkin - bu faqat qo'lda qo'ng'iroq qilishning hojati yo'qligini isbotlash uchun edi .Bind & ltISmurf & gt () qishloqdagi har qanday smurfni aniq bog'lash uchun.

Masalan, siz "Controller" bilan tugamaydigan har qanday narsa, masalan, IDocumentController bilan bog'lanmasligi uchun, ma'lum bir ism maydonida nomlash konventsiyasini bajarishingiz mumkin.

IApplicationShellView uchun echim Ninject ApplicationShellView turiga o'tadi. Va muammo bor:

AOK qiladigan narsa yo'q! Ko'rinish to'liq beton tekshirgich bilan birlashtirilgan! Lekin kuting, nima uchun ko'rinish ota-ona nazorati haqida bilishi kerak?

Siz bu erda qaramlikni bekor qilishingiz kerak (Tekshirish inversiyasi to'g'rimi?) va ko'rinishga ega bo'lish o'rniga so'rab boshqaruvchi nimadir qil, ko'rinishga ega ayt biron bir narsa qilish kerak bo'lgan nazoratchi chunki foydalanuvchi tugmani bosgan.

WinForms - bu men foydalanadigan voqealar haqida.

Tekshirish moslamasi va ko'rinish o'rtasidagi munosabatni teskari yo'naltirish shunchaki aylananing bog'liqligini buzdi: endi tekshiruvchining ko'rinishi kerak bo'lgan voqealarni boshqarish kifoya!