• 您的信息
      • 日期时间
        2025年3月8日 星期六
        【蛇】己卯月丙子日
        乙巳年 二月初九
        妇女节
        您的信息
        您的IP:
        3.145.109.147
        操作系统:
        未知操作系统
        浏览器:
        未知浏览器
        分辨率:
        1280x720
        位置:
        缂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁绘劦鍓欓崝銈囩磽瀹ュ拑韬€殿喖顭烽幃銏ゅ礂鐏忔牗瀚介梺璇查叄濞佳勭珶婵犲伣锝夘敊閸撗咃紲闂佺粯鍔﹂崜娆撳礉閵堝洨纾界€广儱鎷戦煬顒傗偓娈垮枛椤兘骞冮姀銈呯閻忓繑鐗楃€氫粙姊虹拠鏌ュ弰婵炰匠鍕彾濠电姴浼i敐澶樻晩闁告挆鍜冪床闂備胶绮崝锕傚礈濞嗘挸绀夐柕鍫濇川绾剧晫鈧箍鍎遍幏鎴︾叕椤掑倵鍋撳▓鍨灈妞ゎ厾鍏橀獮鍐閵堝懐顦ч柣蹇撶箲閻楁鈧矮绮欏铏规嫚閺屻儱寮板┑鐐板尃閸曨厾褰炬繝鐢靛Т娴硷綁鏁愭径妯绘櫓闂佸憡鎸嗛崪鍐簥闂傚倷鑳剁划顖炲礉閿曞倸绀堟繛鍡樻尭缁€澶愭煏閸繃顥犵紒鈾€鍋撻梻渚€鈧偛鑻晶顖涚箾閻撳海绠婚柛鈺嬬節瀹曟帡濡堕崱娆戔棩闂傚倸鍊风粈浣革耿闁秴纾块柕鍫濐槸閽冪喖鏌ㄩ悢鍝勑㈢痪鎯ь煼閺岀喖宕滆鐢盯鏌¢崨顔惧弨妤犵偞鐗滈崚鎺楀礂婢跺﹣澹曢梺鍦帛鐢晛螞濠婂懐纾介柛灞捐壘閳ь剛鍏橀幃鐐烘晜閼恒儲鐝烽柟鍏肩暘閸斿矂鎮块悙顒傜瘈濠电姴鍊归崳铏光偓瑙勬礀瀵墎鎹㈠☉銏犵闁绘垵娲g欢鐢告⒑閸濄儱鏋庨柟鍐茬箻婵$敻宕熼姘辩潉闂佹悶鍎滈崘鈺佸姃闂傚倷鑳堕崕鐢稿疾濞戙垺鐓€闁挎繂顦拑鐔哥箾閹存瑥鐏╅崬顖炴⒑閹稿孩顥嗘俊顐㈠瀹曨剚寰勬繛鐐杸濡炪倖姊婚妴瀣涘顓犵闁告粌鍟扮粔顔锯偓瑙勬礈婵炩偓鐎殿喕绮欓、姗€鎮欓幓鎺斻偖闂傚倷鑳剁划顖毭洪幋鐘冲闁哄被鍎辩壕濠氭煙閹规劦鍤欐鐐灪缁绘盯骞嬮悙鍨櫘闂佸憡蓱閹倸顫忓ú顏勫窛濠电姳鑳剁换渚€姊洪崫銉バg€光偓閹间礁绠氱€光偓閸曨偆顔婇梺瑙勫劤瑜板鑺辨繝姘拺闂傚牊鐩悰婊呯磼鏉堛劍绀嬫鐐诧躬瀹曞爼鍩為幆褌澹曞┑鐐茬墕閻忔繂鈻嶅鈧弻娑㈡晲韫囨洖鍩岄梺浼欑悼閸忔﹢鐛幒妤€绠i柡鍌濇硶婢ь垶姊绘担鍛婂暈缂侇喖鐭傚畷顖涘鐎涙ǚ鎷诲銈嗙墬缁嬫挾寮ч埀顒勬⒑濮瑰洤鐏叉繛浣冲嫮顩烽柍鍝勬噺閻撴瑦绻涢懠棰濆敽缂併劎鏅埀顒€鐏氬姗€鏁冮鍫濈疇闁绘劕鎼敮閻熸粌绻楅妵鎰版倷椤掑倻鐦堥梺姹囧灲濞佳冪摥婵犵數鍋涢惇浼村磹濡や胶鐝堕柡鍥ュ灩闁裤倖淇婇妶鍕厡闁告ḿ鏁诲铏规喆閸曢潧鏅遍梺鍝ュУ閻楃娀濡撮崒娑氶檮闁告稑锕﹂崢浠嬫⒑鐟欏嫬鍔ょ€规洦鍓熷畷婵嗏堪閸涱垳锛滅紓鍌欑劍宀e灝煤鐎涙﹩娈介柣鎰▕閸庢棃鏌熼鐣屾噰鐎规洖缍婇、鏇㈠閿涘嫬灏嗙紓鍌氬€搁崐鎼佸磹妞嬪孩濯奸柡灞诲劚绾惧鏌熼悙顒€澧柣鏂挎閺屻倝骞栨担瑙勯敪婵犳鍠栭悧鎾诲蓟閿濆绠荤€规洖娲ㄩ鎺楁⒑閸濆嫭婀伴柣鈺婂灡娣囧﹪鎮滈懞銉︽珳闂佸憡渚楅崣搴ㄦ倵閸愭祴鏀介柣妯诲墯閸熷繘鏌涢悩宕囧⒈缂侇喗妫冮幃浠嬪箹閻愨晛浜鹃柛鎰靛枛鍞梺鍐叉惈閸婃悂鍩€椤掑倸鍘撮柡灞稿墲瀵板嫮鈧綆浜炴禒鎼佹煟閻樺弶宸濋柛瀣閻忓啴姊虹紒姗堣€挎繛浣冲嫮顩烽柨鏇楀亾闁伙絾绻堥弫鎰板川椤旈棿娣梻浣虹《閺備線宕戦幘鎰佹富闁靛牆妫楃粭鍌炴煠閸愯尙鍩i柛鈺侊躬瀵挳濮€閿涘嫬寮抽梻浣告惈濞诧箓銆冮崱妞绘瀺闁糕剝鐟х壕濂告煕鐏炲墽鈽夌紒妞绘櫆閵囧嫰鏁冩笟鍥ㄧ秷闂侀€涚┒閸斿秶鎹㈠┑瀣<闁靛牆娲ら幃鎴︽煟鎼淬値娼愭繛鍙夅缚閺侇噣骞掑Δ鈧悡婵嬪箹濞n剙濡肩紒鐘崇⊕閵囧嫰寮幐搴㈠創婵炲濮电敮鎺楀煘閹达附鍋愰柛顭戝亝濮e嫰姊虹粙娆惧剱闁烩晩鍨靛Λ鐔兼⒑閸濆嫷妲归柨娑欐礀鐓ゆい蹇撴噹娴滄粍淇婇悙宸剰閻庢稈鏅涢埢鎾淬偅閸愨斁鎷洪柣鐔哥懃鐎氼剟宕濈捄琛℃斀妞ゆ柨鎼埀顒佺箓椤曪綁骞撻幒鍡樻杸闁诲函缍嗛崑鍡涘储闁秵鐓熼煫鍥ㄦ礀娴犙囨煕鐎n偅宕岄柟顖氬暣楠炲鎮欓鍐泿闂備礁鎼崐鍦偓绗涘泚澶愬閳╁啫寮挎繝鐢靛Т閹冲繘顢旈悩缁樼厵闁荤喐婢橀顓炩攽閳╁啯鍊愬┑锛勫厴閺佸倿骞嗚缁嬪牓姊婚崒姘偓鐑芥嚄閸洖绠犻柟鎹愵嚙閸氬綊鏌″搴″箹缂佺媭鍨堕弻銊╂偆閸屾稑顏� Amazon EC2闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁绘劦鍓欓崝銈囩磽瀹ュ拑韬€殿喖顭烽幃銏ゅ礂鐏忔牗瀚介梺璇查叄濞佳勭珶婵犲伣锝夘敊閸撗咃紲闂佽鍨庨崘锝嗗瘱闂備胶顢婂▍鏇㈠箲閸ヮ剙鐏抽柡鍐ㄧ墕缁€鍐┿亜韫囧海顦﹀ù婊堢畺閺屻劌鈹戦崱娆忓毈缂備降鍔岄妶鎼佸蓟閻斿吋鍎岄柛婵勫劤琚﹂梻浣告惈閻绱炴笟鈧妴浣割潨閳ь剟骞冨▎鎾崇妞ゆ挾鍣ュΛ褔姊婚崒娆戠獢婵炰匠鍏炬稑鈻庨幋鐐存闂佸湱鍎ら〃鎰礊閺嶃劎绡€闂傚牊渚楅崕鎰版煛閸涱喚鍙€闁哄本绋戦埥澶愬础閻愬樊娼绘俊鐐€戦崕鏌ユ嚌妤e啫鐓橀柟瀵稿仜缁犵娀姊虹粙鍖℃敾妞ゃ劌妫濋獮鍫ュΩ閳哄倸鈧鏌﹀Ο渚Ш闁挎稒鐩铏圭磼濡搫顫庨梺绋跨昂閸婃繂鐣烽幋鐘亾閿濆骸鏋熼柣鎾跺枑娣囧﹪顢涘┑鍡楁優濠电姭鍋撳ù鐘差儐閻撳啰鎲稿⿰鍫濈婵炴垶纰嶉鑺ユ叏濮楀棗澧婚柛銈嗘礋閺岀喓绱掗姀鐘崇亪濡炪値鍋勯幊姗€寮诲澶婄厸濞达絽鎲″▓鏌ユ⒑缂佹ḿ绠栨繛鑼枎椤繒绱掑Ο璇差€撻梺鑺ッ敍宥夊箻缂佹ḿ鍙嗗┑顔斤供閸樿绂嶅⿰鍫熺叆闁哄啫娴傞崵娆撴煛鐎c劌鈧妲愰幒鎾寸秶闁靛⿵瀵屽Λ鍐倵濞堝灝鏋熼柟姝屾珪閹便劑鍩€椤掑嫭鐓冮梺娆惧灠娴滈箖姊鸿ぐ鎺濇缂侇噮鍨抽幑銏犫槈濞嗘劗绉堕梺鍛婃寙閸涘懏鑹鹃埞鎴︽倷閸欏鐝旂紓鍌氱С閻掞附绌辨繝鍕ㄥ亾濞戞瑡缂氱紒鈾€鍋撻梻浣规偠閸庮垶宕濇惔銊ュ偍闂侇剙绉甸埛鎴︽偡濞嗗繐顏╅柛鏂诲€栭妵鍕即閵娿儱绠荤紓渚囧枛椤兘骞冨▎鎾村€绘俊顖滃帶楠炲秵淇婇悙顏勨偓鏍ь潖婵犳艾纾婚柟鍓х帛閸婂潡鏌熺粙璺ㄦ槀濞存粍绮撻弻銊╁即濡も偓娴滃墽绱撻崒姘毙㈤柨鏇ㄤ簻椤曪絾绻濆顓炰簻缂佺偓濯芥ご鎼佸疾椤掆偓閳规垿顢欑憴鎺曨潐缁傚秹顢楅崟顐ゎ槷濡炪倖鐗楅閬嶅籍閸喎浜归梻鍌氱墛缁嬫劕鈻介鍡忓亾閸忓浜鹃梺鎸庣箓閻楀﹦娑甸懜鍏哥箚闁告瑥顦慨宥嗩殽閻愭潙娴鐐诧工閻g兘宕惰閻忎線姊虹拠鈥虫灆闁告濞婂畷瑙勩偅閸愩劎顦ч梺鍛婁緱閸欏骸螞濠婂牊鈷掗柛灞剧懅椤︼箑顭块悷甯含闁诡噯绻濆畷濂稿Ψ閵壯嶇幢闂備胶纭堕崜婵嬫偡瑜庣粙澶婎吋閸涘倹妫冮弫鎰板川椤撶喐顔夐梻浣虹帛閹稿鎮烽埡鍛畺婵°倕鎳忛崑銊╂煟瑜戦褏绱炴繝鍌滄殾婵犲﹤鐗嗙涵鈧梺璇茬箺椤曆呯礊婵犲洤绠栭柍鈺佸暞閸庣喖鏌曡箛濠冩珕闁挎稑妫濆缁樻媴閸涘﹥鍎撻梺娲诲墮閵堢ǹ鐣锋导鏉戠疀妞ゆ垼鍋愮槐浼存椤愩垺澶勭紒瀣灩缁牓宕奸姀鈥虫瀾闂婎偄娲︾粙鎴澬ч弻銉︾厽婵☆垵鍋愮敮娑㈡煃闁垮鐏︾紒缁樼洴閹崇姵锛愬┑鍡橆唲婵°倗濮烽崑鐐恒€冮崱娑樜﹂柛鏇ㄥ灠鎯熼梺闈涱樈閸ㄧ敻宕ラ锔解拺閻犲洠鈧櫕鐝紓浣虹帛缁诲牓濡存笟鈧鎾閳╁啯鐝栭梻渚€鈧偛鑻晶鎾煙椤旂晫鎳勭紒缁樼箞瀹曞爼濡歌鐢儳鈹戦悩鍨毄闁稿⿴鍨堕崺鈧い鎺戝绾惧鏌熼悙顒佺伇闁衡偓閼恒儯浜滈柡鍌氱仢閹垿鏌涢悩鎴愭垿骞堥妸锔剧瘈闁告侗鍣禒鈺冪磽娴d粙鍝洪悽顖涘笩閻忔帡鏌i悩鍙夋悙鐎殿喛娉涢埢鎾活敃閿旇В鎷绘繛杈剧到閹诧繝骞夌粙搴撴斀妞ゆ梻鍋撻弳顒勬煙椤斻劌娲﹂崑鎰偓鐟板閸犳牕鈻撻妸锔剧瘈闁汇垽娼ф牎缂佺偓婢樼粔鐟邦嚕閺屻儱绠瑰ù锝呮贡閸樿棄鈹戦埥鍡楃仩闁诲繑绻堥幆鍐倻濡晲绨婚梺鎸庢煥閹碱偅鎱ㄩ崒娑欏弿濠电姴鍟妵婵囦繆椤愩垹鏆欓棁澶愭煏婵炲灝鍔ょ紒澶庢閳ь剝顫夊ú妯好洪悢绗衡偓浣割潩鐠鸿櫣鍔﹀銈嗗坊閸嬫捇鏌i敐鍥у幋妤犵偛顑夐弫鍐焵椤掑倻涓嶅┑鐘崇閸嬶綁鏌涢妷顔荤盎缂佹唻濡囩槐鎺楀础閻愰潧鐓熷┑顔硷攻濡炶棄螞閸愩劉妲堥弶鍫厛閳ь剙妫濆濠氬磼濮橆剦浠奸柣搴㈠嚬閸撶喖宕洪姀銈呯闁哄鍩堥崵銈夋煟鎼淬垻鈯曢懣銈夋煙闁垮銇濇慨濠冩そ瀹曘劍绻濋崘銊╃€洪柣鐔哥矋濠㈡﹢宕婊呯焿鐎广儱鎳夐弨浠嬫煕閵夈垺娅囨い鏃€娲熷娲川婵犲嫭鍣у銇扁偓閸嬫捇姊洪崗鍏肩凡婵炵》绻濆璇测槈閵忕姷鍘搁梺绋挎湰缁秹宕氬☉妯滄棃鎮╅棃娑楁勃闁汇埄鍨辩敮鐔兼倶閸愨晝绠鹃弶鍫濆⒔閸掍即鏌熺喊鍗炰喊闁绘侗鍣e畷濂稿Ψ閿旇瀚奸梺鑽ゅТ濞测晝浜稿▎鎴犱笉闁规儼濮ら悡鏇㈡倵閿濆骸澧柍璇茬墛閵囧嫰濮€閳ヨ弓瀛╁銈忕畱缂嶅﹪寮诲☉銏犵厴闁诡垎鍌氼棜婵犵绱曢崑鎴﹀磹閺嶎偅鏆滃┑鐘叉处閸婂潡鏌ㄩ弬鍨挃闁活厼妫濋幃妤呮晲鎼粹剝鐏嶉梺缁樻尰閻燂箓濡甸崟顖氱睄闁逞屽墴瀵憡绻濆顓炴畬闂佺鍕垫畷闁绘挻绋戦湁闁挎繂姣ヨぐ鎺戞辈闁挎繂娲犻崑鎾舵喆閸曨剛顦ㄩ柣銏╁灡鐢繝宕洪妷锕€绶炲┑鐘插閸嶉潧顪冮妶鍡楀潑闁稿鎸剧槐鎺楁偐閸楃偛绁┑顔硷功缁垶骞忛崨顖滈┏閻庯綆浜濋鍕磽閸屾瑨鍏岀紒顕呭灣閺侇噣鍨惧畷鍥ㄦ闂佺鎻梽鍕磻閹邦厾绠鹃柤纰卞墰鐢盯鏌¢崪浣烽偗闁诡喖鍢查オ浼村礃椤旂厧鍙婃俊銈囧Х閸嬫盯鎮ч幘缈犵箚闁归棿绀侀悡娑樏归敐鍥х殤缂佽鲸鐓″缁樻媴閾忕懓绗¢梺鍛婃⒐濞茬喖銆佸棰濇晣闁靛繒濮撮崑宥夋⒒閸屾氨澧涘〒姘殔閵嗘帗绻濆顓犲帾闂佸壊鍋呯换鍐夐悙鐑樼厽闁规儳宕崝锕傛煛瀹€鈧崰鎾诲窗婵犲洤纭€闁绘劖婢橀弸鍫ユ⒒娴h櫣銆婇柡鍌欑窔瀹曟垿骞橀幇浣瑰瘜闂侀潧鐗嗗Λ妤冪箔閸岀偞鐓犻柛鎰絻椤e磭绱掗纰辩吋妤犵偞岣跨槐鎺懳熼悡搴$闂傚倷鐒︾€笛呮崲閸屾娲Χ婢跺﹤鍋嶉柣搴㈢⊕閿曗晛鈻撴禒瀣厽闁归偊鍘界紞鎴炵箾閹碱厼鏋熸い銊e劦閹瑥顔忛鐓庡闁诲孩顔栭崳顕€宕抽敐澶婃槬闁逞屽墯閵囧嫰骞掗幋婵愪紥缂傚倸绉甸悧婊堝焵椤掆偓缁犲秹宕曢柆宥呯疇濠㈣埖鍔曠紒鈺呮煠閹帒鍔樺ù婊勭矒閺岋繝宕橀妸銉㈠亾婵犳艾绠洪柛灞剧〒缁犻箖鏌涢銈呮瀾闁抽攱鍔曡彁闁搞儜宥堝惈濡炪們鍨哄ú鐔煎极閹版澘骞㈤煫鍥ㄦ煥椤忓搫鈹戦悩娈挎毌闁逞屽墮閸熻法鐥閺屾盯寮埀顒勬偡閳轰緡鍤曟い鎰剁畱缁犺崵绱撴担鑲℃垵鈻嶉姀銈嗏拺閻犳亽鍔屽▍鎰版煙閸戙倖瀚�
        您的天气
          正在获取信息 ...
随笔 - 3461, 文章 - 0, 评论 - 739, 阅读 - 1200万
  管理

C# 插件构架实战

Posted on   lzhdim  阅读(1119)  评论(1编辑  收藏  举报
一、引言

    
1. 问题的引入

    假设你设计的程序已经部署到用户的计算机上,并且能够正常运行了。但是有一天,用户打来了电话——他们要求增加新的功能。确定了用户的需求后,你竟然发现原有的软件架构已经无法胜任新增任务的需求——你需要重新设计这个应用了!但问题是,就算你又用了一个开发周期完成了用户需要的应用,却不能保证用户的需求不会再次变更。也就是说,需求蔓延的可能性依然存在。因此,这种情况下插件构架更能显示出它的优越性。

    
2. 几个解决方案的对比

    我总结了一下我所接触到的插件构架,大致上可分为以下几类: 

i> 脚本式

    使用某种语言把插件的程序逻辑写成脚本代码。而这种语言可以是 Python ,或是其他现存的已经经过用户长时间考验的脚本语言。甚至,你可以自行设计一种脚本语言来配合你程序的特殊需要。当然,用当今最流行的 XML 是再合适不过了。

    这种形式的特点在于,稍有点编程知识的用户就可以自行修改你的脚本( ^_^ 假如你不加密它的话)。我们无法论证这是好处还是坏处。因为,这种情况所造成的后果是不可预知的。 

ii> 动态函数库 DLL

    插件功能以动态库函数的形式存在。主程序通过某种渠道(插件编写者或某些工具)获得插件 DLL 中的函数签名,然后在合适的地方调用它们。用过 Matlab 的读者都知道, Matlab 中的各项功能几乎都是些动态链入的函数。 

iii> 聚合式

    顾名思义,就是把插件功能直接写成 EXE 。主程序除了完成自己的职责外,还负责调度这些“插件”。我不喜欢这种形式。这使插件与插件之间,主程序与插件之间(主要是这一点)的信息交流困难了许多。巴比伦塔的失败 [1] 从某种程度上讲就是信息交流无法实现造成的。 

iv> COM 组件

    COM [2] 的产生给这个世界增添了几分活力。只有接口!我们的插件需要做的只是实现程序定义的接口。主程序不需要知道插件怎样实现预定的功能,它只需要通过接口访问插件,并提供主程序相关对象的接口。这样一来,主程序与各插件之间的信息交流就变得异常简单。并且,插件对于主程序来说是完全透明的。 
 
    
3. 决策

    C# 是面向对象的程序设计语言。它提供了 interface 关键字来直接定义接口。同时, System.Reflection 命名空间也提供了访问外部程序集的一系列相关对象。这就为我们在 C# 中实现插件构架打下了坚实的基础。 

    下面,我们将以一个具有插件构架的程序编辑器为例,来阐述这种构架在 C# 中的实现。 


二、设计过程

    好了,现在我们准备把所有的核心代码都放在 CSPluginKernel 命名空间中。用VSIDE建立一个C#类库工程。在命名空间 CSPluginKernel 中开始我们的代码。

    
1. 接口设计

    我们的程序编辑器会向插件开放正在编辑的文档对象。程序启动后,就枚举每一个插件并把它连接到主程序,同时传递主程序对象的接口。插件可以通过这个接口来请求主程序对象或访问主程序功能 。 

    根据上面的需求,我们首先需要一个主程序接口:
复制  保存
public interface IApplicationObject
{
void Alert(string msg); // 产生一条信息
    void ShowInStatusBar(string msg); // 将指定的信息显示在状态栏
    IDocumentObject QueryCurrentDocument(); // 获取当前使用的文档对象
    IDocumentObject[] QueryDocuments(); // 获取所有的文档对象

// 设置事件处理器
    void SetDelegate(Delegates whichOne, EventHandler targer);
}
// 目前只需要这一个事件

public enum Delegates
{
Delegate_ActiveDocumentChanged
}

然后是 IDocumentObject 接口。插件通过这个接口访问编辑器对象。
复制  保存
///
/// 编辑器对象必须实现这个接口
///
public interface IDocumentObject
{
// 这些属性是 RichTextBox 控件的相应的属性映射

string SelectionText { get; set; }
Color SelectionColor { get; set; }
Font SelectionFont { get; set; }
int SelectionStart { get; set; }
int SelectionLength { get; set; }
string SelectionRTF { get; set; }
bool HasChanges { get; }
void Select(int start, int length);
void AppendText(string str);
void SaveFile(string fileName);
void SaveFile();
void OpenFile(string fileName);
void CloseFile();
}

这个接口不需要过多解释。这里我只实现了RichTextBox控件少数的几个方法,其他可能用得到的,读者自行添加即可。

   再然后,根据插件在其生命周期里的行为,设计插件的接口。
复制  保存
///
/// 本程序的插件必须实现这个接口
///
public interface IPlugin
{
ConnectionResult Connect(IApplicationObject app);
void OnDestory();
void OnLoad();
void Run();
}
///
/// 表示插件与主程序连接的结果
///
public enum ConnectionResult
{
Connection_Success,
Connection_Failed
}

主程序会首先调用 Connect() 方法,并传递 IApplicationObject 给插件。插件在这个过程中做一些初始化工作。然后,插件的 OnLoad() 方法被调用。在这之后,当主程序接收到调用插件的信号时(键盘、鼠标响应)就会调用插件的 Run() 方法来启动这个插件。程序结束时,调用其 OnDestory() 方法。这样,插件的生命才宣告结束。

   
2. 插件信息的存储与获取

    一个插件需要有它的名称 、版本等信息。作为设计者的你,也一定要留下你的尊姓大名和个人网站等用来宣传自己。 C# 的新特性——属性, 就是一个很好的解决方案。因此我们定义一个从 System.Attribute 继承来的类 PluginInfoArrtibute :
复制  保存
///
/// 用来指定一个插件的相关信息
///
public class PluginInfoAttribute : System.Attribute
{
///
    /// Deprecated. Do not use.
    ///

public PluginInfoAttribute() { }
public PluginInfoAttribute(
string name, string version,
string author, string webpage, bool loadWhenStart)
{
// 细节已略去
    }
public string Name { get { return _Name; } }
public string Version { get { return _Version; } }
public string Author { get { return _Author; } }
public string Webpage { get { return _Webpage; } }
public bool LoadWhenStart { get { return _LoadWhenStart; } }
///
    /// 用来存储一些有用的信息
    ///
    public object Tag
{
get { return _Tag; }
set { _Tag = value; }
}
///
    /// 用来存储序号
    ///
    public int Index
{
get { return _Index; }
set { _Index = value; }
}
private string _Name = "";
private string _Version = "";
private string _Author = "";
private string _Webpage = "";
private object _Tag = null;
private int _Index = 0;
// 暂时不会用
    private bool _LoadWhenStart = true;
}
//用这个类修饰你的插件,并让他实现 IPlugin 接口:

///
/// My Pluging 1( Just for test )
///
[PluginInfo(
"My Pluging 1( Just for test )",
"1.0",
"Jack H Hansen",
"http://blog.csdn.net/matrix2003b", true)
]
public class MyPlugin1 : IPlugin
{
public MyPlugin1() { }

#region IPlugin 成员

// 细节已略去

#endregion

private IApplicationObject _App;
private IDocumentObject _CurDoc;
}


3. 加载插件

     现在就得用到 System.Refelction 命名空间了。程序在启动时会搜索 plugins 目录下的每一个文件。对于每一个文件,如果它是一个插件,就用 Assembly 对象加载它。然后枚举程序集中的每一个对象。判断一个程序集是否为我们的插件的方法是判断它是否直接或间接实现自 IPlugin。用下面的函数,传递从程序集枚举的对象的System.Type。
复制  保存
private bool IsValidPlugin(Type t)
{
bool ret = false;
Type[] interfaces = t.GetInterfaces();
foreach (Type theInterface in interfaces)
{
if (theInterface.FullName == "CSPluginKernel.IPlugin")
{
ret = true;
break;
}
}
return ret;
}

若条件都满足,IsValidPlugin() 就会返回 true 。接着程序就会创建这个对象并把它存于一个 ArrayList 中。
复制  保存
plugins.Add(pluginAssembly.CreateInstance(plugingType.FullName));

     现在,你就可以撰写测试代码了。


三、源代码

     由于篇幅所限,完整的源代码(包含测试用例)请在下面的链接下载。
http://www.pscode.com/Upload_PSC/ftp/C__Plugin_1774987282004.zip
     下载后请用 VS.NET2003 打开,重新生成解决方案即可(需要 .NET Framework 1.1)。测试用例是一个在 RichTextBox 控件里插入红色文本的插件。很简单,只作测试之用。


四、结语

     That's all! 有了这种插件构架,可怜的程序员们就再也不用为需求蔓延耗费心机了。另外,欢迎对本文以及本文的附加代码作出评价。还有,就是,常去我的 Blog 看看~~ ^_^


注:

[1] 巴比伦塔的失败   《人月神话》,Frederick P. Brooks Jr.  第 7 章 为什么巴比伦塔会失败 

[2] COM   有关 COM/COM+ 的详细技术细节请参见《 Mastering COM and COM+ 》 , Ash Rofail , Yasser Shohoud.
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2025年3月8日 星期六 【蛇】己卯月丙子日 乙巳年 二月初九 妇女节
您的IP:3.145.109.147,操作系统:未知操作系统,浏览器:未知浏览器
Copyright (C) 2000-2025 Lzhdim Software All Rights Reserved
点击右上角即可分享
微信分享提示