.NET: علاج التبعية

من لم يواجه مشاكل بسبب إعادة توجيه التجميع؟ على الأرجح ، سيواجه كل من طور تطبيقًا كبيرًا نسبيًا هذه المشكلة عاجلاً أم آجلاً.

الآن أعمل في JetBrains ، في مشروع JetBrains Rider ، وأنا منخرط في مهمة ترحيل Rider إلى .NET Core. شاركت سابقًا في البنية التحتية المشتركة في Circuit ، وهي منصة استضافة التطبيقات المستندة إلى السحابة.



تحت النص هو نص تقريري من مؤتمر DotNext 2019 في موسكو ، حيث تحدثت عن الصعوبات عند العمل مع التجميعات في .NET وأظهرت مع أمثلة عملية ما يحدث وكيفية التعامل معه.


في جميع المشاريع التي عملت فيها كمطور .NET ، كان علي التعامل مع العديد من المشاكل المتعلقة بربط التبعيات وتحميل التجميعات. سنتحدث عن هذا.

هيكل الوظائف:


  1. قضايا التبعية
  2. تحميل صارم للحفارة

  3. دوت نت كور

  4. تنزيلات مجموعة التصحيح


ما هي بعض قضايا التبعية؟


عندما بدأوا في تطوير .NET Framework في أوائل العقد الأول من القرن الحادي والعشرين ، كانت مشكلة جحيم التبعية معروفة بالفعل عندما سمح المطورون في جميع المكتبات بتعطيل التغييرات ، وأصبحت هذه المكتبات غير متوافقة للاستخدام مع التعليمات البرمجية المترجمة بالفعل. كيف تحل مثل هذه المشكلة؟ الحل الأول واضح. حافظ دائمًا على التوافق مع الإصدارات السابقة. بالطبع ، هذا ليس واقعيًا جدًا ، لأن كسر التغيير من السهل جدًا وضعه في التعليمات البرمجية. على سبيل المثال:



كسر التغييرات ومكتبات .NET

هذا مثال خاص بـ .NET. لدينا طريقة ، وقررنا إضافة معلمة ذات قيمة افتراضية لها. سيستمر الكود في التجميع إذا قمنا بإعادة تجميعه ، لكن ثنائي سيكون طريقتين مختلفتين تمامًا: طريقة واحدة تحتوي على وسيطات صفرية ، والطريقة الثانية لها وسيطة واحدة. إذا قام المطور داخل التبعية بكسر التوافق العكسي بهذه الطريقة ، فلن نتمكن من استخدام الرمز الذي تم تجميعه مع هذا الاعتماد على الإصدار السابق.

الحل الثاني لمشاكل التبعية هو إضافة إصدار للمكتبات ، والتجمعات - أي شيء. قد تكون هناك قواعد مختلفة للإصدار ، والنقطة هي أنه يمكننا بطريقة ما تمييز الإصدارات المختلفة من نفس المكتبة عن بعضها البعض ، ويمكنك أن تفهم ما إذا كان التحديث سينكسر أم لا. لسوء الحظ ، بمجرد تقديم الإصدارات ، يظهر نوع مختلف من المشاكل.



جحيم الإصدار هو عدم القدرة على استخدام تبعية متوافقة مع الخيارات الثنائية ، ولكن في نفس الوقت لديه إصدار لا يتناسب مع وقت التشغيل أو مكون آخر يتحقق من هذه الإصدارات. في .NET ، من المظاهر النموذجية للجحيم الإصدار FileLoadException ، على الرغم من أن الملف يقع على القرص ، ولكن لسبب ما لا يتم تحميله مع وقت التشغيل.



في .NET ، تحتوي التجميعات على العديد من الإصدارات المختلفة - حاولوا إصلاح جحيم الإصدارات بطرق مختلفة ، ومعرفة ما حدث. لدينا حزمة System.Collections.Immutable. يعرفه الكثير من الناس. لديه أحدث إصدار من حزمة NuGet 1.6.0. يحتوي على مكتبة ، تجميع مع الإصدار 1.2.4.0. لقد تلقيت أنه ليس لديك إصدار مكتبة الإنشاء 1.2.4.0. كيف نفهم أنه يكمن في حزمة 1.6.0 NuGet؟ لن تكون سهلة. بالإضافة إلى إصدار التجميع ، تحتوي هذه المكتبة على العديد من الإصدارات الأخرى. على سبيل المثال ، إصدار ملف التجميع ، إصدار معلومات التجميع. تحتوي حزمة NuGet هذه في الواقع على ثلاث مجموعات مختلفة بنفس الإصدارات (للإصدارات المختلفة من .NET Standard). معيار

.NET Document
Opbuild

تمت كتابة الكثير من الوثائق حول كيفية العمل مع التجميعات في .NET. هناك دليل .NET لتطوير التطبيقات الحديثة لـ .NET مع مراعاة .NET Framework و .NET Standard و .NET Core والمصدر المفتوح وكل ما يمكن أن يكون. تم تخصيص حوالي 30٪ من المستند بالكامل لتحميل التجميعات. سنقوم بتحليل مشاكل وأمثلة محددة قد تنشأ.

لماذا كل هذا ضروري؟ أولاً ، لتجنب السير على أشعل النار. ثانيًا ، يمكنك أن تجعل الحياة أسهل لمستخدمي المكتبات الخاصة بك لأنه مع مكتبتك لن يواجهوا مشاكل التبعية التي اعتادوا عليها. سيساعدك أيضًا على التعامل مع ترحيل التطبيقات المعقدة إلى .NET Core. وفوق كل ذلك ، يمكنك أن تصبح SRE ، هذا مهندس إعادة توجيه أول (ملزم) ، والذي يأتي إليه كل فرد في الفريق ويسأل عن كيفية كتابة إعادة توجيه أخرى.

تجميع صارم تحميل


تحميل التجميع الصارم هو المشكلة الرئيسية التي يواجهها المطورون على .NET Framework. يتم التعبير عنه في FileLoadException. قبل الانتقال إلى تجميع صارم لتحميل نفسه ، دعني أذكرك ببعض الأشياء الأساسية.

عند إنشاء تطبيق .NET ، يكون الإخراج عبارة عن بعض القطع الأثرية ، والتي توجد عادةً في Bin / Debug أو في Bin / Release ، وتحتوي على مجموعة معينة من تجميعات التجميع وملفات التكوين. سوف تشير التجميعات إلى بعضها البعض حسب الاسم واسم التجميع. من المهم أن نفهم أن روابط التجميع تقع مباشرة في التجميع الذي يشير إلى هذا التجميع ؛ لا توجد ملفات تكوين سحرية حيث تتم كتابة مراجع التجميع. على الرغم من أنه قد يبدو لك أن هذه الملفات موجودة. المراجع في التجميعات نفسها في شكل ثنائي.

في .NET ، هناك عملية حل التجميع - هذا عندما يتم تحويل تعريف التجميع بالفعل إلى تجميع حقيقي ، والذي يكون على القرص أو يتم تحميله في مكان ما في الذاكرة. يتم تنفيذ حل التجميع مرتين: في مرحلة الإنشاء ، عندما يكون لديك مراجع في * .csproj ، وفي وقت التشغيل ، عندما يكون لديك مراجع داخل التجميعات ، وتتحول في بعض القواعد إلى تجميعات يمكن تنزيلها.

// Simple name
MyAssembly، الإصدار = 6.0.0.0،
Culture = Neutral، PublicKeyToken = null

// Strong name
Newtonsoft.Json، الإصدار = 6.0.0.0،
Culture = Neutral، PublicKeyToken = 30ad4fe6b2a6aeed // PublicKey


دعنا ننتقل إلى المشكلة. اسم التجميع هناك نوعان رئيسيان. النوع الأول من اسم التجميع هو اسم بسيط. يسهل التعرف عليها من خلال حقيقة أن PublicKeyToken = خالية. هناك اسم قوي ، من السهل التعرف عليهم بحقيقة أن PublicKeyToken ليس فارغًا ، ولكن بعض القيمة.



لنأخذ مثالاً. لدينا برنامج يعتمد على المكتبة مع أدوات MyUtils ، وإصدار MyUtils هو 9.0.0.0. البرنامج نفسه له ارتباط بمكتبة أخرى. تريد هذه المكتبة أيضًا استخدام MyUtils ، ولكن الإصدار 6.0.0.0. إصدار MyUtils 9.0.0.0 ، والإصدار 6.0.0.0 لهما PublicKeyToken = خالية ، أي أن لهما اسمًا بسيطًا. ما الإصدار الذي سيقع في الأداة الثنائية ، 6.0.0.0 أو 9.0.0.0؟ الإصدار التاسع. هل يمكن لـ MyLibrary استخدام الإصدار 9.0.0.0 من MyUtils ، الذي دخل في الأداة الثنائية؟



في الواقع ، يمكن ذلك ، لأن MyUtils لها اسم بسيط ، وبالتالي ، لا يوجد تحميل تجميع صارم لذلك.



مثال آخر. بدلاً من MyUtils ، لدينا مكتبة كاملة من NuGet ، والتي تحمل اسمًا قويًا. معظم المكتبات في NuGet لها اسم قوي.



في مرحلة البناء ، يتم نسخ الإصدار 9.0.0.0 إلى BIN ، ولكن في وقت التشغيل نحصل على النسخة الشهيرة FileLoadException. لكي تتمكن MyLibrary من استخدام الإصدار 6.0.0.0 حتى Newtonsoft.Jsonتتمكن من استخدام الإصدار 9.0.0.0 ، يجب أن تذهب وتكتب Binding redirect to App.config.

عمليات إعادة التوجيه الملزمة





إعادة توجيه إصدارات التجميع

تنص على أنه يجب إعادة توجيه التجميع الذي يحمل هذا الاسم ومفتاح publicKeyToken من مثل هذا النطاق من الإصدارات إلى مثل هذا النطاق من الإصدارات. يبدو أنه سجل بسيط للغاية ، ولكنه مع ذلك موجود هنا App.config، ولكن يمكن أن يكون في ملفات أخرى. يوجد ملف machine.configداخل .NET Framework ، داخل وقت التشغيل ، يتم فيه تحديد مجموعة قياسية من عمليات إعادة التوجيه ، والتي قد تختلف من إصدار إلى إصدار من .NET Framework. قد يحدث أنه في 4.7.1 لا يعمل شيء لك ، ولكن على 4.7.2 يعمل بالفعل ، أو العكس. عليك أن تضع في اعتبارك أن عمليات إعادة التوجيه لا يمكن أن تأتي فقط من عمليات إعادة التوجيه الخاصة بك .App.config، ويجب أخذ ذلك في الاعتبار عند تصحيح الأخطاء.

نحن نبسط كتابة عمليات إعادة التوجيه


لا أحد يريد كتابة عمليات إعادة التوجيه الملزمة بأيديهم. دعونا نعطي هذه المهمة ل MSBuild!



كيفية تمكين وتعطيل إعادة التوجيه التلقائي للربط

بعض النصائح حول كيفية تبسيط العمل مع إعادة التوجيه الملزمة. النصيحة الأولى: تمكين Binding من إعادة التوجيه التلقائي في MSBuild. تم تشغيله بواسطة الملكية في *.csproj. عند إنشاء مشروع ، سيقع في قطعة أثرية ثنائية App.config، مما يشير إلى عمليات إعادة التوجيه إلى إصدارات المكتبات الموجودة في نفس الأداة. هذا يعمل فقط لتشغيل التطبيقات ، تطبيق وحدة التحكم ، WinExe. بالنسبة للمكتبات ، هذا لا يعمل ، لأن المكتباتApp.configغالبًا ما تكون غير ملائمة ، لأنها ذات صلة بتطبيق يقوم بتشغيل التجميعات وتحميلها بنفسها. إذا قمت بإجراء تكوين للمكتبة ، فقد تختلف بعض التبعيات في التطبيق عن تلك التي كانت عند بناء المكتبة ، وتبين أن تكوين المكتبة ليس له معنى كبير. ومع ذلك ، في بعض الأحيان بالنسبة لتكوينات المكتبات لا تزال منطقية.



الوضع عندما نكتب الاختبارات. توجد الاختبارات عادةً في ClassLibrary وهي تحتاج أيضًا إلى عمليات إعادة توجيه. يمكن لأطر الاختبار أن تدرك أن المكتبة التي تحتوي على اختبارات تحتوي على تهيئة dll ، وتتبادل عمليات إعادة التوجيه الموجودة فيها للحصول على الرمز من الاختبارات. يمكنك إنشاء عمليات إعادة التوجيه هذه تلقائيًا. إذا كان لدينا تنسيق قديم*.csproj، وليس على غرار SDK ، يمكنك الذهاب بطريقة بسيطة ، وتغيير OutputType إلى Exe وإضافة نقطة إدخال فارغة ، وهذا سيجبر MSBuild على إنشاء عمليات إعادة توجيه. يمكنك الذهاب في الاتجاه الآخر واستخدام الاختراق. يمكنك إضافة خاصية أخرى إليه *.csproj، مما يجعل MSBuild يعتبر أنه بالنسبة لـ OutputType ، لا تزال بحاجة إلى إنشاء عمليات إعادة توجيه ملزمة. هذه الطريقة ، على الرغم من أنها تبدو وكأنها اختراق ، ستسمح لك بإنشاء عمليات إعادة توجيه للمكتبات التي لا يمكن إعادة إنشائها في Exe ، ولأنواع أخرى من المشاريع (باستثناء الاختبارات).

بالنسبة إلى التنسيق الجديد ، *.csprojسيتم إنشاء عمليات إعادة التوجيه نفسها إذا كنت تستخدم Microsoft.NET.Test.Sdk الحديث.

النصيحة الثالثة: لا تستخدم توليد إعادة التوجيه الملزم مع NuGet. لدى NuGet القدرة على إنشاء إعادة توجيه Binding للمكتبات التي تنتقل من الحزم إلى أحدث الإصدارات ، ولكن هذا ليس الخيار الأفضل. يجب إضافة جميع عمليات إعادة التوجيه هذه App.configوالتزامها بها ، وإذا أنشأت عمليات إعادة توجيه باستخدام MSBuild ، فسيتم إنشاء عمليات إعادة التوجيه أثناء الإنشاء. إذا ارتكبتها ، فقد يكون لديك دمج الصراعات. يمكنك ببساطة أن تنسى تحديث إعادة توجيه Binding في الملف ، وإذا تم إنشاؤها أثناء الإنشاء ، فلن تنسى.



حل مرجع التجميع
توليد عمليات إعادة التوجيه الملزمة

الواجب المنزلي لأولئك الذين يرغبون في فهم أفضل لكيفية عمل جيل عمليات إعادة التوجيه الملزمة: اكتشف كيف يعمل ، انظر هذا في التعليمات البرمجية. انتقل إلى دليل .NET ، وانتقل إلى كل مكان باستخدام خاصية الاسم ، والتي يتم استخدامها لتمكين الإنشاء. هذا هو نهج شائع بشكل عام ، إذا كان هناك بعض الخصائص الغريبة لـ MSBuild ، يمكنك الذهاب والاستفادة من استخدامه. لحسن الحظ ، يتم استخدام الخاصية عادةً في تكوينات XML ، ويمكنك العثور على استخدامها بسهولة.

إذا قمت بفحص ما هو موجود في أهداف XML هذه ، فسترى أن هذه الخاصية تؤدي إلى مهمتين MSBuild. تسمى المهمة الأولى ResolveAssemblyReferences، وتولد مجموعة من عمليات إعادة التوجيه المكتوبة على الملفات. المهمة الثانية GenerateBindingRedirectsتكتب نتائج المهمة الأولىApp.config. هناك منطق XML يصحح بشكل طفيف تشغيل المهمة الأولى ويزيل بعض عمليات إعادة التوجيه غير الضرورية أو يضيف عمليات إعادة توجيه جديدة.

بديل لـ XML Configs


ليس من المناسب دائمًا الاحتفاظ بعمليات إعادة التوجيه في تهيئة XML. قد يكون لدينا موقف يقوم فيه التطبيق بتنزيل المكون الإضافي ، ويستخدم هذا البرنامج المساعد مكتبات أخرى تتطلب عمليات إعادة توجيه. في هذه الحالة ، قد لا نكون على دراية بمجموعة عمليات إعادة التوجيه التي نحتاجها ، أو قد لا نرغب في إنشاء XML. في مثل هذه الحالة ، يمكننا إنشاء AppDomain ، وعند إنشائه ، لا يزال النقل إليه حيث يوجد XML مع عمليات إعادة التوجيه الضرورية. يمكننا أيضًا التعامل مع أخطاء تحميل التجميع في وقت التشغيل. Rantime .NET يعطي مثل هذه الفرصة.

AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) => 
{ 
   var name = eventArgs.Name; 
   var requestingAssembly = eventArgs.RequestingAssembly; 
   
   return Assembly.LoadFrom(...); // PublicKeyToken should be equal
};


لها حدث يسمى CurrentDomain.AssemblyResolve. من خلال الاشتراك في هذا الحدث ، سوف نتلقى أخطاء حول جميع تنزيلات التجميع الفاشلة. نحصل على اسم التجميع الذي لم يتم تحميله ، ونحصل على تجميع التجميع الذي طلب تحميل التجميع الأول. هنا يمكننا تحميل التجميع يدويًا من المكان الصحيح ، على سبيل المثال ، إسقاط الإصدار ، وأخذه فقط من الملف ، وإرجاع هذا الحدث من المعالج. أو قم بإرجاع قيمة فارغة إذا لم يكن لدينا شيء لإرجاعه ، إذا لم نتمكن من تحميل التجميع. يجب أن يكون PublicKeyToken هو نفسه ، والتجمعات مع PublicKeyToken مختلفة ليست بأي شكل من الأشكال أصدقاء مع بعضهم البعض.



ينطبق هذا الحدث على مجال تطبيق واحد فقط. إذا أنشأ المكون الإضافي لدينا AppDomain بداخله ، فلن تعمل عملية إعادة التوجيه هذه في وقت التشغيل فيها. تحتاج إلى الاشتراك بطريقة أو بأخرى في هذا الحدث في جميع AppDomain التي أنشأها البرنامج المساعد. يمكننا القيام بذلك باستخدام AppDomainManager.

AppDomainManager هو تجميع منفصل يحتوي على فئة تطبق واجهة معينة ، وستسمح لك إحدى طرق هذه الواجهة بتهيئة أي AppDomain جديد تم إنشاؤه في التطبيق. بمجرد إنشاء AppDomain ، سيتم استدعاء هذه الطريقة. في ذلك يمكنك الاشتراك في هذا الحدث.

تجميع صارم للتحميل و .NET Core


لا توجد مشكلة في .NET Core تسمى "تحميل التجميع الصارم" ، ويرجع ذلك إلى حقيقة أن التجميعات الموقعة تتطلب بالضبط الإصدار المطلوب. هناك شرط آخر. بالنسبة لكافة التجميعات ، بغض النظر عما إذا كانت موقعة باسم قوي أم لا ، يتم التحقق من أن الإصدار الذي تم تحميله في وقت التشغيل أكبر من أو يساوي الإصدار السابق. إذا كنا في حالة تطبيق يحتوي على مكونات إضافية ، فقد يكون لدينا مثل هذا الوضع الذي تم جمع المكون الإضافي ، على سبيل المثال ، من إصدار جديد من SDK ، والتطبيق الذي يتم تنزيله عليه يستخدم الإصدار القديم من SDK حتى الآن ، وبدلاً من الانهيار يمكننا أيضًا الاشتراك في هذا الحدث ، ولكن بالفعل في .NET Core ، وكذلك تحميل التجميع الذي لدينا. يمكننا كتابة هذا الرمز:
AppDomain.CurrentDomain.AssemblyResolve += (s, eventArgs) => 
{ 
     CheckForRecursion(); 
     var name = eventArgs.Name;
     var requestingAssembly = eventArgs.RequestingAssembly; 
    
     name.Version = new Version(0, 0); 
     
     return Assembly.Load(name); 
};


لدينا اسم التجميع الذي لم يتم التمهيد ، نقوم بإبطال الإصدار واستدعاؤه Assembly.Loadمن نفس الإصدار. لن يكون هناك عودية هنا ، لأنني راجعت العودية بالفعل.



كان من الضروري تنزيل الإصدار 0.0.2.0 من MyUtils. في BIN ، لدينا الإصدار 0.0.1.0 MyUtils. لقد قمنا بإعادة التوجيه من الإصدار 0.0.2.0 إلى الإصدار 0.0. لن يتم تحميل الإصدار 0.0.1.0 معنا. سوف يخرج خروج لنا لأنه لم يكن من الممكن تحميل التجميع مع الإصدار 0.0.2 16-1 . 2 16-1 .

new Version(0, 0) == new Version(0, 0, -1, -1) 

class Version { 
     readonly int _Build; 
     readonly int _Revision; 
     readonly int _Major; 
     readonly int _Minor; 
} 
(ushort) -1 == 65535


في فئة الإصدار ، ليست كل المكونات إلزامية ، وبدلاً من المكونات الاختيارية –1 يتم تخزينها ، ولكن في مكان ما بالداخل ، يحدث تجاوز للحد ، ويتم الحصول على 2 16-1 . إذا كنت مهتمًا ، يمكنك محاولة العثور على مكان حدوث الفائض بالضبط.



إذا كنت تعمل مع تجميعات الانعكاس وتريد الحصول على جميع الأنواع ، فقد يتبين أنه لا يمكن لجميع الأنواع الحصول على طريقة GetTypes. يحتوي التجميع على فئة ترث من فئة أخرى موجودة في تجميع لم يتم تحميله.

static IEnumerable GetTypesSafe(this Assembly assembly) 
{ 
    try 
    { 
        return assembly.GetTypes(); 
    }
    catch (ReflectionTypeLoadException e) 
   { 
        return e.Types.Where(x => x != null); 
    } 
}



في هذه الحالة ، ستكون المشكلة أنه سيتم طرح ReflectionTypeLoadException. في الداخل ReflectionTypeLoadExceptionهناك خاصية لا تزال هناك أنواع يمكن تحميلها. ليست كل المكتبات الشعبية تأخذ هذا الأمر بعين الاعتبار. AutoMapper ، واحد على الأقل من إصداراته ، إذا واجه مع ReflectionTypeLoadException ، سقط للتو ، بدلاً من الذهاب واختيار الأنواع من داخل الاستثناء.

تسمية قوية


التجميعات ذات الأسماء القوية

لنتحدث عن أسباب تحميل التجميع الصارم ، وهذا هو الاسم القوي.
الاسم القوي هو توقيع التجميع بواسطة بعض المفاتيح الخاصة باستخدام التشفير غير المتماثل. PublicKeyToken هو تجزئة المفتاح العمومي لهذا التجميع.

تسمح لك التسمية القوية بالتمييز بين التجميعات المختلفة التي تحمل نفس الاسم. على سبيل المثال ، MyUtils ليس اسمًا فريدًا ، قد يكون هناك العديد من التجميعات التي تحمل نفس الاسم ، ولكن إذا قمت بتسجيل اسم قوي ، فسيكون لديهم PublicKeyToken مختلفًا ويمكننا تمييزها بهذه الطريقة. مطلوب اسم قوي لبعض سيناريوهات تحميل التجميع.

على سبيل المثال ، من أجل تثبيت تجميع في ذاكرة التخزين المؤقت للتجميع العمومي أو لتنزيل العديد من الإصدارات جنبًا إلى جنب في وقت واحد. الأهم من ذلك ، يمكن أن تشير التجميعات المسماة القوية فقط إلى التجميعات المسماة الأخرى القوية. نظرًا لأن بعض المستخدمين يريدون توقيع إصداراتهم باسم قوي ، يقوم مطورو المكتبات أيضًا بتوقيع مكتباتهم ، بحيث يسهل على المستخدمين تثبيتها ، بحيث لا يضطر المستخدمون إلى إعادة توقيع هذه المكتبات.

الاسم القوي: الإرث؟


تسمية قوية ومكتبات .NET

تقول Microsoft صراحةً على MSDN أنه لا يجب استخدام اسم قوي لأغراض أمنية ، فهي توفر فقط لتمييز التجميعات المختلفة التي تحمل نفس الاسم. لا يمكن تغيير مفتاح التجميع بأي شكل من الأشكال ؛ إذا قمت بتغييره ، فسوف توقف عمليات إعادة التوجيه لجميع المستخدمين. إذا كان لديك جزء خاص من المفتاح للاسم القوي تم تسريبه للوصول العام ، فلا يمكنك سحب هذا التوقيع بأي شكل من الأشكال. لا يوفر تنسيق ملف SNK الذي يوجد فيه الاسم القوي مثل هذه الفرصة ، وتحتوي التنسيقات الأخرى لتخزين المفاتيح على الأقل على ارتباط بقائمة إبطال شهادات CRL ، والتي يمكن من خلالها فهم أن هذه الشهادة لم تعد صالحة. لا يوجد شيء من هذا القبيل في SNK.

يحتوي الدليل المفتوح المصدر على التوصيات التالية. أولاً ، بالإضافة إلى ذلك لأغراض أمنية ، استخدم تقنيات أخرى. ثانيًا ، إذا كانت لديك مكتبة مفتوحة المصدر ، يُقترح عمومًا أن تقوم بتخصيص الجزء الخاص من المفتاح إلى المستودع ، بحيث يكون من الأسهل على الأشخاص أن يقوموا بتشكيل مكتبتك ، وإعادة بنائها ووضعها في تطبيق جاهز. ثالثًا ، لا تغير أبدًا الاسم القوي. مدمرة للغاية. على الرغم من حقيقة أنها مدمرة للغاية ومكتوبة عنها في دليل المصدر المفتوح ، إلا أن Microsoft تواجه أحيانًا مشاكل مع مكتباتها الخاصة.



هناك مكتبة تسمى System.Reactive. في السابق ، كانت هذه العديد من حزم NuGet ، واحدة منها هي Rx-Linq. هذا مجرد مثال ، وهو نفس الشيء بالنسبة لبقية الحزم. في الإصدار الثاني ، تم توقيعه باستخدام مفتاح Microsoft. في الإصدار الثالث ، انتقل إلى المستودع في مشروع github.com/dotnet وبدأ في الحصول على توقيع .NET Foundation. المكتبة ، في الواقع ، غيرت اسم قوي. تمت إعادة تسمية حزمة NuGet ، ولكن تم استدعاء التجميع بالداخل تمامًا كما كان من قبل. كيفية إعادة التوجيه من الإصدار الثاني إلى الثالث؟ لا يمكن القيام بعملية إعادة التوجيه هذه.

التحقق من الاسم القوي


كيفية القيام بما يلي: تعطيل ميزة تجاوز الاسم القوية

حجة أخرى أن الاسم القوي هو بالفعل شيء من الماضي ولا يزال رسميًا بحتًا هو أنه لم يتم التحقق منه. لدينا تجميع موقّع ونريد إصلاح نوع من الأخطاء فيه ، ولكن ليس لدينا إمكانية الوصول إلى المصادر. يمكننا فقط أخذ dnSpy - هذه أداة تسمح لك بفك التجميعات المترجمة بالفعل وإصلاحها. كل شيء سيعمل من أجلنا. لأنه افتراضيًا ، يتم تمكين تجاوز التحقق من الاسم القوي ، أي أنه يتحقق فقط من أن PublicKeyToken متساوٍ ، ولا يتم التحقق من سلامة التوقيع نفسه. قد تكون هناك دراسات بيئية لا يزال يتم فيها التحقق من التوقيع ، وهنا مثال حي على ذلك هو IIS. يتم التحقق من سلامة التوقيع على IIS (يتم تعطيل تجاوز التحقق من صحة الاسم بشكل افتراضي) ، وسوف ينكسر كل شيء إذا قمنا بتحرير التجميع الموقع.

إضافة:يمكنك تعطيل التحقق من التوقيع للتجميع باستخدام العلامة العامة. باستخدامه ، يتم استخدام المفتاح العام فقط للتوقيع ، مما يضمن سلامة اسم التجميع. يتم نشر المفاتيح العامة التي تستخدمها Microsoft هنا .
في Rider ، يمكن تمكين العلامة العامة في خصائص المشروع.





متى يجب تغيير إصدارات التجميع

يقدم الدليل المفتوح المصدر أيضًا بعض سياسات الإصدار ، والغرض منها تقليل عدد عمليات إعادة التوجيه والتغييرات الضرورية للمستخدمين على NET Framework. سياسة الإصدار هذه هي أنه لا ينبغي لنا تغيير إصدار التجميع باستمرار. يمكن أن يؤدي هذا ، بالطبع ، إلى مشاكل في التثبيت في GAC ، بحيث لا تتوافق الصورة الأصلية المثبتة مع التجميع ويجب عليك إجراء تجميع JIT مرة أخرى ، ولكن ، في رأيي ، هذا أقل شرًا من مشاكل الإصدار. في حالة CrossGen ، لا يتم تثبيت التجميعات الأصلية على مستوى العالم - لن تكون هناك مشاكل.

على سبيل المثال ، تحتوي حزمة NuGet Newtonsoft.Json على عدة إصدارات: 12.0.1 و 12.0.2 وما إلى ذلك - كل هذه الحزم لها تجميع مع الإصدار 12.0.0.0. التوصية هي أنه يجب تحديث إصدار التجميع عند تغيير إصدار رئيسي من حزمة NuGet.

الموجودات


اتبع النصائح الخاصة بـ .NET Framework: قم بإنشاء عمليات إعادة التوجيه يدويًا وحاول استخدام نفس الإصدار من التبعيات في جميع المشاريع في الحل الخاص بك. سيؤدي ذلك إلى تقليل عدد عمليات إعادة التوجيه إلى حد كبير. لا تحتاج إلى تسمية قوية إلا إذا كان لديك سيناريو تحميل محدد للبناء حيث تكون هناك حاجة إليه ، أو إذا كنت تقوم بتطوير مكتبة وترغب في تبسيط الحياة للمستخدمين الذين يحتاجون حقًا إلى تسمية قوية. لا تغير الاسم القوي.

.NET القياسي


ننتقل إلى .NET Standard. إنه مرتبط ارتباطًا وثيقًا بإصدار الجحيم في .NET Framework. .NET Standard عبارة عن أداة لكتابة المكتبات المتوافقة مع التطبيقات المختلفة للنظام الأساسي .NET. تشير عمليات التنفيذ إلى .NET Framework و .NET Core و Mono و Unity و Xamarin.



* رابط للوثائق

هذا هو جدول دعم .NET القياسي للإصدارات المختلفة من إصدارات مختلفة من أوقات التشغيل. وهنا يمكننا أن نرى أن .NET Framework لا يدعم بأي شكل من الأشكال الإصدار .NET القياسي 2.1. لم يتم التخطيط لإصدار .NET Framework ، الذي سيدعم .NET Standard 2.1 والإصدارات الأحدث ، حتى الآن. إذا كنت تقوم بتطوير مكتبة وتريد أن تعمل للمستخدمين على .NET Framework ، فسيتعين عليك أن يكون لديك هدف لـ .NET Standard 2.0. بالإضافة إلى حقيقة أن .NET Framework لا يدعم أحدث إصدار من .NET Standard ، فلننتبه إلى العلامة النجمية. يدعم .NET Framework 4.6.1 .NET Standard 2.0 ، ولكن مع علامة النجمة. توجد حاشية سفلية مباشرة في الوثائق ، حيث حصلت على هذا الجدول.



خذ بعين الاعتبار مشروع مثال. تطبيق على .NET Framework له تبعية واحدة تستهدف .NET Standard. شيء من هذا القبيل: ConsoleApp و ClassLibrary. الهدف المكتبة القياسية .NET. عندما نضع هذا المشروع معًا ، سيكون مثل هذا في BIN الخاص بنا.



سيكون لدينا مائة ملف DLL هناك ، منها ملف واحد فقط يتعلق بالتطبيق ، وكل شيء آخر جاء لدعم .NET Standard. الحقيقة هي أن .NET Standard 2.0 ظهر في وقت لاحق عن .NET Framework 4.6.1 ، ولكن في نفس الوقت تبين أنه متوافق مع API ، وقرر المطورون إضافة دعم Standard 2.0 إلى .NET 4.6.1. لم نفعل ذلك أصلاً (من خلال التضمين netstandard.dllفي وقت التشغيل نفسه) ، ولكن بطريقة يتم بها وضع .NET Standard * .dll وجميع واجهات التجميع الأخرى مباشرة في BIN.



إذا نظرنا إلى تبعيات إصدار .NET Framework الذي نستهدفه وعدد المكتبات التي تقع في BIN ، سنرى أنه لا يوجد الكثير منها في 4.7.1 ، وبما أن 4.7.2 لا توجد مكتبات إضافية على الإطلاق و .NET المعيار معتمد هناك أصلاً.



هذه تغريدة من أحد مطوري .NET ، والتي تصف هذه المشكلة وتوصي باستخدام الإصدار 4.7.2 من .NET Framework إذا كان لدينا مكتبات .NET القياسية. ليس حتى مع الإصدار 2.0 هنا ، ولكن مع الإصدار 1.5.

الموجودات


إن أمكن ، ارفع إطار الهدف في مشروعك إلى 4.7.1 على الأقل ، ويفضل 4.7.2. إذا كنت تقوم بتطوير مكتبة لجعل الحياة أسهل لمستخدمي المكتبة ، قم بعمل هدف منفصل لـ .NET Framework ، وسوف يتجنب عددًا كبيرًا من dlls التي يمكن أن تتعارض مع شيء ما.

دوت نت كور


لنبدأ بنظرية عامة. سنناقش كيف أطلقنا JetBrains Rider على .NET Core ، ولماذا يجب أن نتحدث عنه على الإطلاق. Rider هو مشروع كبير جدًا ، ولديه حل مشروع ضخم مع عدد كبير من المشاريع المختلفة ، ونظام معقد من التبعيات ، لا يمكنك فقط أخذه والترحيل إلى وقت تشغيل آخر في وقت واحد. للقيام بذلك ، علينا استخدام بعض الاختراقات ، والتي سنحللها أيضًا.

تطبيق .NET Core


كيف يبدو تطبيق .NET Core النموذجي؟ يعتمد على كيفية نشره بالضبط ، وما الذي سيفعله في النهاية. يمكن أن يكون لدينا عدة سيناريوهات. الأول هو نشر يعتمد على الإطار. هذا هو نفسه الموجود في .NET Framework عندما يستخدم التطبيق وقت التشغيل المثبت مسبقًا على جهاز الكمبيوتر. يمكن أن يكون نشرًا مكتفيًا ذاتيًا ، وذلك عندما يحمل التطبيق وقت تشغيل. وقد يكون هناك نشر ملف واحد ، وهذا عندما نحصل على ملف exe واحد ، ولكن في حالة .NET Core داخل هذا الملف exe يوجد قطعة أثرية في تطبيق مستقل ، هذا أرشيف يتم استخراجه ذاتيًا.



سننظر فقط في النشر المعتمد على الإطار. لدينا دلل مع التطبيق ، هناك ملفان التكوين ، الأول مطلوب ، هذا runtimeconfig.jsonوdeps.json. بدءًا من .NET Core 3.0 ، يتم إنشاء ملف exe مطلوب لجعل التطبيق أكثر ملاءمة للتشغيل ، بحيث لا تحتاج إلى إدخال الأمر .NET إذا كنا على Windows. تقع التبعيات في هذا العنصر ، بدءًا من .NET Core 3.0 ، في .NET Core 2.1 ، تحتاج إلى نشر أو استخدام خاصية أخرى في *.csproj.

الأطر المشتركة ، .runtimeconfig.json





.runtimeconfig.jsonيحتوي على إعدادات وقت التشغيل اللازمة لتشغيله. يشير إلى إطار العمل المشترك الذي سيتم تشغيل التطبيق فيه ، ويبدو ذلك. نشير إلى أن التطبيق سيتم تشغيله تحت الإصدار 3.0.0 من "Microsoft.NETCore.App" ، قد يكون هناك إطار عمل مشترك آخر. قد تكون الإعدادات الأخرى هنا أيضًا. على سبيل المثال ، يمكنك تمكين جامع القمامة الخادم.



.runtimeconfig.jsonولدت خلال تجميع المشروع. وإذا أردنا تضمين الخادم GC ، فإننا نحتاج إلى تعديل هذا الملف مسبقًا بطريقة ما ، حتى قبل أن نجمع المشروع ، أو نضيفه يدويًا. يمكنك إضافة إعداداتك هنا مثل هذا. يمكننا إما تضمين خاصية في *.csproj، إذا تم توفير هذه الخاصية من قبل مطوري .NET ، أو إذا لم يتم توفير الخاصية ، يمكننا إنشاء ملف يسمىruntimeconfig.template.jsonوكتابة الإعدادات اللازمة هنا. أثناء التجميع ، ستتم إضافة الإعدادات الضرورية الأخرى إلى هذا القالب ، على سبيل المثال ، نفس إطار العمل المشترك.



الإطار المشترك عبارة عن مجموعة من وقت التشغيل والمكتبات. في الواقع ، نفس الشيء مثل وقت تشغيل .NET Framework ، الذي كان يتم تثبيته للتو مرة واحدة على الجهاز وللأبد كان إصدار واحد. إطار العمل المشترك ، وخلافا لوقت تشغيل .NET Framework واحد ، يمكن إصداره ، يمكن للتطبيقات المختلفة استخدام إصدارات مختلفة من أوقات التشغيل المثبتة. كما يمكن توريث الإطار المشترك. يمكن عرض الإطار المشترك نفسه في مثل هذه المواقع الموجودة على القرص والتي يتم تثبيتها بشكل عام على النظام.



هناك العديد من إطارات العمل المشتركة القياسية ، على سبيل المثال ، Microsoft.NETCore.App ، الذي يقوم بتشغيل تطبيقات وحدة التحكم التقليدية ، AspNetCore.App ، لتطبيقات الويب ، و WindowsDesktop.App ، وهو إطار العمل المشترك الجديد في .NET Core 3 ، والذي يقوم بتشغيل تطبيقات سطح المكتب. في Windows Forms و WPF. يكمل الإطاران المشتركان الأخيران بشكل أساسي الإطار الأول المطلوب لتطبيقات وحدة التحكم ، أي أنهما لا يحملان وقت تشغيل جديدًا بالكامل ، ولكنهما ببساطة يكملان الإطار الحالي بالمكتبات اللازمة. يبدو هذا الميراث وكأنه يوجد أيضًا في أدلة إطار العمل المشترك runtimeconfig.jsonالتي تم تحديد إطار العمل المشترك الأساسي فيها.

بيان التبعية ( .deps.json)



الفحص الافتراضي - .NET Core

ملف التكوين الثاني هو هذا .deps.json. يحتوي هذا الملف على وصف لجميع تبعيات التطبيق أو الإطار المشترك أو المكتبة والمكتبات .deps.jsonأيضًا. يحتوي على جميع التبعيات ، بما في ذلك التبعيات. ويختلف سلوك وقت تشغيل .NET Core بناءً على ما إذا كان .deps.jsonالتطبيق يحتوي عليه أم لا. إذا .deps.jsonلم يكن الأمر كذلك ، فسيتمكن التطبيق من تحميل كافة التجميعات الموجودة في إطار العمل المشترك الخاص به أو في دليل BIN الخاص به. إذا كان هناك .deps.json، يتم تمكين التحقق. إذا لم يكن أحد التجميعات المذكورة في القائمة .deps.json، فلن يبدأ التطبيق ببساطة. سترى الخطأ المعروض أعلاه. إذا حاول التطبيق تحميل بعض التجميع في وقت التشغيل ، والذي.deps.json إذا ، على سبيل المثال ، باستخدام طرق تحميل التجميع أو أثناء عملية حل التجميعات ، فسترى خطأ مشابهًا جدًا لتحميل التجميع الصارم.

متسابق Jetbrains


رايدر هو .NET IDE. لا يعلم الجميع أن Rider هو IDE يتكون من واجهة أمامية تستند إلى IntelliJ IDEA ومكتوبة بلغة Java و Kotlin ، وواجهة خلفية. الواجهة الخلفية هي في الأساس R # ، والتي يمكنها التواصل مع IntelliJ IDEA. هذه الواجهة الخلفية هي تطبيق .NET عبر الأنظمة الأساسية الآن.
أين تعمل؟ يستخدم Windows .NET Framework المثبت على جهاز الكمبيوتر الخاص بالمستخدم. في أنظمة المعلومات الأخرى ، على Linux و Mac ، يتم استخدام Mono.

هذا ليس حلاً مثاليًا عندما يكون هناك أوقات تشغيل مختلفة في كل مكان ، وأريد الوصول إلى الحالة التالية بحيث يعمل Rider على .NET Core. من أجل تحسين الأداء ، لأن جميع الميزات الأخيرة في .NET Core مرتبطة بهذا. لتقليل استهلاك الذاكرة. الآن هناك مشكلة في كيفية عمل Mono مع الذاكرة.

سيسمح لك التبديل إلى .NET Core بالتخلي عن التقنيات القديمة وغير المدعومة ويسمح بإصلاح بعض الإصلاحات للمشكلات التي تم العثور عليها في وقت التشغيل. سيسمح لك التبديل إلى .NET Core بالتحكم في إصدار وقت التشغيل ، أي أن Rider لن يعمل بعد ذلك على .NET Framework المثبت على جهاز الكمبيوتر الخاص بالمستخدم ، ولكن على إصدار محدد من .NET Core ، والذي يمكن حظره ، كنشر مستقل. سيسمح الانتقال إلى .NET Core في النهاية باستخدام واجهات برمجة التطبيقات الجديدة التي يتم استيرادها بشكل خاص في Core.

الآن الهدف هو إطلاق نموذج أولي ، إطلاقه ، فقط للتحقق من كيفية عمله ، ما هي نقاط الفشل المحتملة ، أي المكونات التي يجب إعادة كتابتها مرة أخرى ، والتي تتطلب معالجة عالمية.

الميزات التي تجعل ترجمة Rider إلى .NET Core صعبة


يتعطل Visual Studio ، حتى إذا لم يتم تثبيت R # فيه ، من Out Of Memory على الحلول الكبيرة ، التي توجد بداخلها مشاريع ذات نمط SDK * .csproj . إن نمط .csproj على غرار SDK هو أحد الشروط الرئيسية لنقل .NET Core بالكامل.

هذه مشكلة لأن Rider يعتمد على R # ، فهم يعيشون في نفس المستودع ، ويريد مطورو R # استخدام Visual Studio لتطوير منتجهم الخاص في منتجهم من أجل صنعه كطعام. في R # هناك روابط مكتبات محددة لإطار العمل الذي تحتاج إلى القيام بشيء ما. في Windows ، يمكننا استخدام Framework لتطبيقات سطح المكتب ، وفي Linux و Mac ، يتم استخدام Mock بالفعل في مكتبات Windows بأقل الوظائف.

القرار


قررنا أن نبقى على القديمة حتى الآن *.csproj، والتجمع في إطار كامل ، ولكن بما أن التجميعات من الإطار و Core متوافقة ثنائية ، قم بتشغيلها على Core. نحن لا نستخدم الميزات غير المتوافقة ، ونضيف جميع ملفات التهيئة الضرورية يدويًا ونقوم بتنزيل إصدارات خاصة من التبعيات لـ .NET Core ، إن وجدت.

ما الاختراقات التي كان عليك الذهاب إليها؟


اختراق واحد: نريد استدعاء طريقة متاحة فقط في Framework ، على سبيل المثال ، هذه الطريقة مطلوبة في R # ، ولكن ليس على Core. تكمن المشكلة في أنه إذا لم تكن هناك طريقة ، فستقع الطريقة التي تستدعيها أثناء تجميع JIT في وقت سابق MissingMethodException. أي أن الطريقة غير الموجودة دمرت الطريقة التي تسميها.

static void Method() { 
  if (NetFramework) 
     CallNETFrameworkOnlyMethod();

  ... 
} 
[MethodImpl(MethodImplOptions.NoInlining)] 
static void CallNETFrameworkOnlyMethod() { 
  NETFrameworkOnlyMethod(); 
}


الحل هنا: نقوم بإجراء مكالمات إلى طرق غير متوافقة في طرق منفصلة. هناك مشكلة أخرى: قد تصبح هذه الطريقة مضمنة ، وبالتالي فإننا نضع علامة عليها بسمة NoInlining.

الاختراق رقم 2: نحن بحاجة إلى أن نكون قادرين على تحميل التجميعات في المسارات النسبية. لدينا تجميع واحد للإطار ، هناك إصدار خاص لـ .NET Core. كيف يمكننا تنزيل إصدار .NET Core لـ .NET Core؟



سوف يساعدونا .deps.json. دعونا نلقي نظرة على .deps.jsonمكتبة System.Diagnostics.PerformanceCounter. مثل هذه المكتبة رائعة من حيث موقعها.deps.json. يحتوي على قسم وقت التشغيل ، حيث يشار إلى نسخة واحدة من المكتبة بمسارها النسبي. في هذه المكتبة ، سيتم تحميل التجميع في جميع أوقات التشغيل ، وهو يرمي فقط عمليات الإعدام. على سبيل المثال ، إذا تم تحميله على Linux ، فإن PerformanceCounter لا يعمل على التصميم على Linux ، ويطير PlatformNotSupportedException من هناك. هناك أيضًا .deps.jsonقسم runtimeTargets في هذا المكان ، وقد تمت الإشارة هنا بالفعل إلى إصدار هذا التجميع خصيصًا لنظام التشغيل Windows ، حيث يجب أن يعمل PerformanceCounter.

إذا أخذنا قسم وقت التشغيل وكتبنا فيه المسار النسبي إلى المكتبة التي نريد تحميلها ، فلن يساعدنا ذلك. يعين قسم وقت التشغيل بالفعل المسار النسبي داخل حزمة NuGet ، وليس نسبيًا إلى رقم التعريف الشخصي. إذا بحثنا عن هذا التجميع في BIN ، فسيتم استخدام اسم الملف فقط من هناك. يحتوي قسم runtimeTargets بالفعل على مسار نسبي صادق ، مسار صادق نسبة إلى BIN. سنحدد مسارًا نسبيًا لمجموعاتنا في قسم runtimeTargets. بدلاً من معرّف وقت التشغيل ، وهو "الفوز" هنا ، يمكننا أن نأخذ معرّفًا آخر نحبه. على سبيل المثال ، سنكتب معرف وقت التشغيل "أي" ، وسيتم تحميل هذا التجميع بشكل عام على جميع الأنظمة الأساسية. أو سنكتب "unix" ، وسيتم تشغيله على Linux ، و Mac ، وما إلى ذلك.

الاختراق التالي: نريد التنزيل على Linux و Mac Mock لبناء WindowsBase. تكمن المشكلة في أن التجميع المسمى WindowsBase موجود بالفعل في Framework Shared Microsoft.NETCore.App، حتى إذا لم نكن على Windows. في Windows Shared Framework ، Microsoft.WindowsDesktop.Appيعيد WindowsBase تعريف الإصدار الموجود NETCore.App. دعونا نلقي نظرة على .deps.jsonهذا الإطار ، وبشكل أكثر دقة في تلك الأقسام التي تصف WindowsBase.



هنا هو الفرق:



إذا تعارضت بعض المكتبات وكانت موجودة في عدة .deps.json، فسيتم تحديد الحد الأقصى منها للزوج المكون من assemblyVersionو fileVersion. يقول دليل .NET fileVersionأنه لا يلزم عرضه إلا في مستكشف Windows ، ولكنه ليس كذلك ، فهو يقع في.deps.json. هذه هي الحالة الوحيدة التي أعرفها عندما يتم استخدام الإصدار الموصوف في الواقع .deps.json، assemblyVersionو fileVersion. في جميع الحالات الأخرى ، رأيت سلوكًا بصرف النظر عن النسخ التي .deps.jsonتمت كتابتها ، سيستمر التجميع في التحميل على أي حال.



الإختراق الرابع. المهمة: لدينا ملف .deps.json للاختراقين السابقين ، ولا نحتاجه إلا لتبعيات محددة. نظرًا لأنها يتم .deps.jsonإنشاؤها في الوضع شبه اليدوي ، لدينا برنامج نصي ، وفقًا لبعض وصف ما يجب أن يصل إلى هناك ، وينشئه أثناء البناء ، نريد أن نحافظ على هذا .deps.jsonالحد الأدنى قدر الإمكان حتى نتمكن من فهم ما فيه. نريد تعطيل التحقق من الصحة والسماح بتنزيل التجميعات الموجودة في BIN ولكن لم يتم وصفها في .deps.json.

الحل: تمكين التكوين المخصص في runtimeconfig. هذا الإعداد مطلوب بالفعل للتوافق مع الإصدارات السابقة مع .NET Core 1.0.

الموجودات


لذا ، .runtime.jsonوعلى .deps.json.NET Core - هذه هي نظائرها App.config. App.configتتيح لك القيام بنفس الأشياء ، على سبيل المثال ، تحميل التجميعات بطرق نسبية. باستخدام .deps.json، وإعادة كتابته يدويًا ، يمكنك تخصيص تحميل التجميعات على .NET Core ، إذا كان لديك سيناريو معقد للغاية.

تنزيلات مجموعة التصحيح


لقد تحدثت عن بعض أنواع المشاكل ، لذلك يجب أن تكون قادرًا على تصحيح المشكلات في تحميل التجميعات. ما الذي يمكن أن يساعد في ذلك؟ أولاً ، تكتب أوقات التشغيل سجلات حول كيفية تحميل التجميعات. ثانيًا ، يمكنك إلقاء نظرة أكثر قربًا على عمليات الإعدام التي تطير إليك. يمكنك أيضًا التركيز على أحداث وقت التشغيل.

سجلات الانصهار





العودة إلى الأساسيات: استخدام عارض سجل الانصهار لتصحيح الأخطاء الغامضة
الانصهار

تسمى آلية تحميل التجميعات في .NET Framework الانصهار ، وهي تعرف كيفية تسجيل ما فعلته بالقرص. لتمكين التسجيل ، تحتاج إلى إضافة إعدادات خاصة إلى التسجيل. هذا ليس مناسبًا جدًا ، لذلك من المنطقي استخدام الأدوات المساعدة ، وهي Fusion Log Viewer و Fusion ++. يعد Fusion Log Viewer أداة مساعدة قياسية تأتي مع Visual Studio ويمكن تشغيلها من سطر أوامر Visual Studio ، موجه أوامر مطور Visual Studio. فيوجن ++ هو نظير مفتوح المصدر لهذه الأداة بواجهة أجمل.



يشبه Fusion Log Viewer هذا. هذا أسوأ من WinDbg لأن هذه النافذة لا تمتد حتى. ومع ذلك ، يمكنك اختراق علامات الاختيار هنا ، على الرغم من أنه ليس من الواضح دائمًا أي مجموعة من علامات الاختيار صحيحة.



يحتوي Fusion ++ على زر "بدء التسجيل" ، ثم يظهر زر "إيقاف التسجيل". في ذلك ، يمكنك رؤية جميع السجلات حول تحميل التجميعات ، وقراءة السجلات حول ما كان يحدث بالضبط. تبدو هذه السجلات شيء من هذا القبيل بطريقة موجزة.



هذا استثناء من تحميل التجميع الصارم. إذا نظرنا إلى سجلات Fusion ، فسنلاحظ أننا بحاجة إلى تنزيل الإصدار 9.0.0.0 بعد معالجة جميع التكوينات. وجدنا ملفًا يشتبه فيه أن لدينا التجميع الذي نحتاجه. لقد رأينا أن الإصدار 6.0.0.0 موجود في هذا الملف. لدينا تحذير من أننا قارنا الأسماء الكاملة للتجميعات ، وهي تختلف في النسخة الرئيسية. ثم حدث خطأ - عدم تطابق الإصدار.

أحداث وقت التشغيل





تسجيل أحداث وقت التشغيل

في Mono ، يمكنك تمكين التسجيل باستخدام متغيرات البيئة ، وستتم كتابة السجلات في النهاية إلى stdoutو stderr. ليس مناسبًا جدًا ، لكن الحل يعمل.



الفحص الافتراضي -
تتبع المستندات / تصميم المستندات الأساسية / تصميم

.NET Core. يحتوي .NET Core أيضًا على متغير بيئة خاص COREHOST_TRACEيتضمن تسجيل الدخول stderr. باستخدام .NET Core 3.0 ، يمكنك كتابة السجلات إلى ملف عن طريق تحديد المسار إليه في متغير COREHOST_TRACEFILE.


هناك حدث ينطلق عندما يفشل تحميل التجميعات. هذا حدث AssembleResolve. هناك حدث مفيد ثاني ، هذا FirstChanceException. يمكنك الاشتراك فيه والحصول على خطأ حول تحميل التجميعات ، حتى لو كتب أحدهم حاول .. قبض على جميع عمليات التنفيذ في المكان الذي فاتهFileLoadExceptionحدث. إذا كان التطبيق قد تم تجميعه بالفعل ، يمكنك تشغيله perfview، ويمكنه مراقبة عمليات تنفيذ .NET ، وهناك يمكنك العثور على تلك المتعلقة بتنزيل الملفات.

الموجودات


انقل العمل إلى الأدوات ، إلى أدوات التطوير ، إلى IDE ، إلى MSBuild ، مما يسمح لك بإنشاء عمليات إعادة توجيه. يمكنك التبديل إلى .NET Core ، ثم ستنسى ما هو Strict Assembly Loading ، وستتمكن من استخدام واجهة برمجة التطبيقات الجديدة تمامًا مثلما نريد تحقيقها في Rider. إذا قمت بتوصيل مكتبة .NET Standard ، فقم برفع الإصدار المستهدف من .NET Framework إلى 4.7.1 على الأقل. إذا كنت تبدو في وضع ميئوس منه ، فابحث عن الاختراقات أو استخدمها أو اختر الاختراقات الخاصة بك في المواقف اليائسة. وتسليح نفسك بأدوات التصحيح.

أوصي بشدة بقراءة الروابط التالية:



DotNext 2020 Piter . , 8 JUG Ru Group.

All Articles