[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-22-haqn-tabaiyat-rust-servicelocator-arc-trait-objects":3},{"article":4,"author":51},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":31,"related_articles":32},"d9000000-0000-0000-0000-000000000122","a0000000-0000-0000-0000-000000000096","Deep EVM #22: حقن التبعيات في Rust — ServiceLocator وArc وTrait Objects","deep-evm-22-haqn-tabaiyat-rust-servicelocator-arc-trait-objects","أنماط حقن التبعيات في Rust: نمط ServiceLocator، Arc لمشاركة الحالة، كائنات السمات للتجريد، واختبار المكونات بشكل مستقل.","## حقن التبعيات بدون إطار عمل\n\nRust ليس لديها حاوية IoC مدمجة مثل Spring أو .NET. بدلاً من ذلك، نستخدم نظام الأنواع والسمات (Traits) لتحقيق حقن التبعيات.\n\n## نمط ServiceLocator\n\n```rust\nuse std::sync::Arc;\n\npub struct ServiceLocator {\n    pub db_pool: Arc\u003CPgPool>,\n    pub chain_store: Arc\u003Cdyn ChainStore + Send + Sync>,\n    pub rpc_client: Arc\u003Cdyn RpcClient + Send + Sync>,\n    pub event_bus: Arc\u003CEventBus>,\n}\n\nimpl ServiceLocator {\n    pub fn new(config: &Config) -> Result\u003CSelf> {\n        let db_pool = Arc::new(PgPool::connect(&config.database_url).await?);\n        let chain_store = Arc::new(PgChainStore::new(db_pool.clone()));\n        let rpc_client = Arc::new(HttpRpcClient::new(&config.rpc_url));\n        let event_bus = Arc::new(EventBus::new(10000));\n        \n        Ok(Self { db_pool, chain_store, rpc_client, event_bus })\n    }\n}\n```\n\n## السمات (Traits) للتجريد\n\n```rust\n#[async_trait]\npub trait ChainStore: Send + Sync {\n    async fn save_chain(&self, chain: &Chain) -> Result\u003C()>;\n    async fn get_chain(&self, id: Uuid) -> Result\u003COption\u003CChain>>;\n    async fn list_profitable(&self, min_profit: U256) -> Result\u003CVec\u003CChain>>;\n}\n\n\u002F\u002F التنفيذ الحقيقي\npub struct PgChainStore {\n    pool: Arc\u003CPgPool>,\n}\n\n#[async_trait]\nimpl ChainStore for PgChainStore {\n    async fn save_chain(&self, chain: &Chain) -> Result\u003C()> {\n        sqlx::query(\"INSERT INTO chains ...\")\n            .execute(&*self.pool)\n            .await?;\n        Ok(())\n    }\n}\n\n\u002F\u002F تنفيذ وهمي للاختبار\npub struct MockChainStore {\n    chains: Mutex\u003CVec\u003CChain>>,\n}\n\n#[async_trait]\nimpl ChainStore for MockChainStore {\n    async fn save_chain(&self, chain: &Chain) -> Result\u003C()> {\n        self.chains.lock().await.push(chain.clone());\n        Ok(())\n    }\n}\n```\n\n## Arc لمشاركة الحالة\n\n`Arc\u003CT>` (Atomic Reference Counting) يسمح بمشاركة البيانات بين خيوط متعددة بأمان:\n\n```rust\nlet locator = Arc::new(ServiceLocator::new(&config).await?);\n\n\u002F\u002F كل مكون يحصل على نسخة من Arc\nlet searcher = ArbSearcher::new(locator.clone());\nlet executor = BundleExecutor::new(locator.clone());\nlet monitor = BlockMonitor::new(locator.clone());\n\ntokio::spawn(searcher.run());\ntokio::spawn(executor.run());\ntokio::spawn(monitor.run());\n```\n\n## الفوائد\n\n1. **قابلية الاختبار** — استبدال التنفيذات الحقيقية بوهمية\n2. **فصل المسؤوليات** — كل مكون يعرف فقط السمة وليس التنفيذ\n3. **المرونة** — تغيير التنفيذ دون تغيير المستهلكين\n\n## الخلاصة\n\nحقن التبعيات في Rust يعتمد على السمات وArc بدلاً من حاويات IoC. النتيجة: كود آمن للأنواع وقابل للاختبار ومفصول بدون حمل وقت التشغيل.","\u003Ch2 id=\"\">حقن التبعيات بدون إطار عمل\u003C\u002Fh2>\n\u003Cp>Rust ليس لديها حاوية IoC مدمجة مثل Spring أو .NET. بدلاً من ذلك، نستخدم نظام الأنواع والسمات (Traits) لتحقيق حقن التبعيات.\u003C\u002Fp>\n\u003Ch2 id=\"servicelocator\">نمط ServiceLocator\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-rust\">use std::sync::Arc;\n\npub struct ServiceLocator {\n    pub db_pool: Arc&lt;PgPool&gt;,\n    pub chain_store: Arc&lt;dyn ChainStore + Send + Sync&gt;,\n    pub rpc_client: Arc&lt;dyn RpcClient + Send + Sync&gt;,\n    pub event_bus: Arc&lt;EventBus&gt;,\n}\n\nimpl ServiceLocator {\n    pub fn new(config: &amp;Config) -&gt; Result&lt;Self&gt; {\n        let db_pool = Arc::new(PgPool::connect(&amp;config.database_url).await?);\n        let chain_store = Arc::new(PgChainStore::new(db_pool.clone()));\n        let rpc_client = Arc::new(HttpRpcClient::new(&amp;config.rpc_url));\n        let event_bus = Arc::new(EventBus::new(10000));\n        \n        Ok(Self { db_pool, chain_store, rpc_client, event_bus })\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"traits\">السمات (Traits) للتجريد\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-rust\">#[async_trait]\npub trait ChainStore: Send + Sync {\n    async fn save_chain(&amp;self, chain: &amp;Chain) -&gt; Result&lt;()&gt;;\n    async fn get_chain(&amp;self, id: Uuid) -&gt; Result&lt;Option&lt;Chain&gt;&gt;;\n    async fn list_profitable(&amp;self, min_profit: U256) -&gt; Result&lt;Vec&lt;Chain&gt;&gt;;\n}\n\n\u002F\u002F التنفيذ الحقيقي\npub struct PgChainStore {\n    pool: Arc&lt;PgPool&gt;,\n}\n\n#[async_trait]\nimpl ChainStore for PgChainStore {\n    async fn save_chain(&amp;self, chain: &amp;Chain) -&gt; Result&lt;()&gt; {\n        sqlx::query(\"INSERT INTO chains ...\")\n            .execute(&amp;*self.pool)\n            .await?;\n        Ok(())\n    }\n}\n\n\u002F\u002F تنفيذ وهمي للاختبار\npub struct MockChainStore {\n    chains: Mutex&lt;Vec&lt;Chain&gt;&gt;,\n}\n\n#[async_trait]\nimpl ChainStore for MockChainStore {\n    async fn save_chain(&amp;self, chain: &amp;Chain) -&gt; Result&lt;()&gt; {\n        self.chains.lock().await.push(chain.clone());\n        Ok(())\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"arc\">Arc لمشاركة الحالة\u003C\u002Fh2>\n\u003Cp>\u003Ccode>Arc&lt;T&gt;\u003C\u002Fcode> (Atomic Reference Counting) يسمح بمشاركة البيانات بين خيوط متعددة بأمان:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">let locator = Arc::new(ServiceLocator::new(&amp;config).await?);\n\n\u002F\u002F كل مكون يحصل على نسخة من Arc\nlet searcher = ArbSearcher::new(locator.clone());\nlet executor = BundleExecutor::new(locator.clone());\nlet monitor = BlockMonitor::new(locator.clone());\n\ntokio::spawn(searcher.run());\ntokio::spawn(executor.run());\ntokio::spawn(monitor.run());\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"\">الفوائد\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\u003Cstrong>قابلية الاختبار\u003C\u002Fstrong> — استبدال التنفيذات الحقيقية بوهمية\u003C\u002Fli>\n\u003Cli>\u003Cstrong>فصل المسؤوليات\u003C\u002Fstrong> — كل مكون يعرف فقط السمة وليس التنفيذ\u003C\u002Fli>\n\u003Cli>\u003Cstrong>المرونة\u003C\u002Fstrong> — تغيير التنفيذ دون تغيير المستهلكين\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">الخلاصة\u003C\u002Fh2>\n\u003Cp>حقن التبعيات في Rust يعتمد على السمات وArc بدلاً من حاويات IoC. النتيجة: كود آمن للأنواع وقابل للاختبار ومفصول بدون حمل وقت التشغيل.\u003C\u002Fp>\n","ar","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:32.801073Z","حقن التبعيات في Rust — ServiceLocator وArc وTrait Objects","حقن التبعيات في Rust: ServiceLocator وArc وكائنات السمات للتجريد والاختبار.","Rust حقن تبعيات",null,"index, follow",[22,27],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000022","Performance","performance","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000001","Rust","rust","الهندسة",[33,39,45],{"id":34,"title":35,"slug":36,"excerpt":37,"locale":12,"category_name":31,"published_at":38},"d0000000-0000-0000-0000-000000000686","لماذا Bali تتحول إلى مركز تكنولوجيا التأثير في جنوب شرق آسيا 2026","limadha-bali-tatahawwal-markaz-tiknulujia-attathir-janub-sharq-asia-2026","تحتل Bali المرتبة 16 بين أنظمة الشركات الناشئة في جنوب شرق آسيا. مع تركيز متزايد لبناة Web3 وشركات AI المستدامة الناشئة وشركات تكنولوجيا السفر البيئي، تنحت الجزيرة مكانتها كعاصمة تكنولوجيا التأثير في المنطقة.","2026-03-28T10:44:50.120618Z",{"id":40,"title":41,"slug":42,"excerpt":43,"locale":12,"category_name":31,"published_at":44},"d0000000-0000-0000-0000-000000000685","فسيفساء حماية البيانات في ASEAN: قائمة امتثال للمطورين","fusayfisa-himayat-albayanat-asean-qaimat-imtithal-lilmutawwirin","تمتلك سبع دول في ASEAN الآن قوانين شاملة لحماية البيانات، لكل منها نماذج موافقة ومتطلبات توطين وهياكل عقوبات مختلفة. إليك قائمة امتثال عملية للمطورين الذين يبنون تطبيقات متعددة البلدان.","2026-03-28T10:44:50.114369Z",{"id":46,"title":47,"slug":48,"excerpt":49,"locale":12,"category_name":31,"published_at":50},"d0000000-0000-0000-0000-000000000684","التحول الرقمي في Indonesia بقيمة 29 مليار دولار: فرص لشركات البرمجيات","attahawwul-arraqami-indonesia-29-milyar-dular-furas-sharikat-albarmajiyat","من المتوقع أن يصل سوق خدمات تكنولوجيا المعلومات في Indonesia إلى 29.03 مليار دولار في 2026، ارتفاعاً من 24.37 مليار دولار في 2025. البنية التحتية السحابية والذكاء الاصطناعي والتجارة الإلكترونية ومراكز البيانات تقود أسرع نمو في جنوب شرق آسيا.","2026-03-28T10:44:50.092728Z",{"id":13,"name":52,"slug":53,"bio":54,"photo_url":19,"linkedin":19,"role":55,"created_at":56,"updated_at":56},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]