Runtime: هل يجب أن يكون هناك إصدار .Net Standard 2.0 من Reflection.Emit؟

تم إنشاؤها على ٢٧ أبريل ٢٠١٨  ·  58تعليقات  ·  مصدر: dotnet/runtime

System.Reflection.Emit ليس جزءًا من .Net Standard ، ولكن هناك حزم تتيح لك استخدامه من مكتبة NET Standard (على وجه التحديد ، System.Reflection.Emit و System.Reflection.Emit.Lightweight ). لكن هذه الحزم لا تحتوي على إصدار .Net Standard 2.0 ، فقط إصدارات .Net Standard 1.x.

هذا له بعض الآثار:

  • لا يمكن لمكتبات .Net Standard 2.0 استخدام typeBuilder.CreateType() (على الرغم من أن هذا الرمز يعمل على .Net Framework 4.6.1 و .Net Core 2.0) ويجب استخدام typeBuilder.CreateTypeInfo().AsType() بدلاً من ذلك. من الممكن أيضًا وجود واجهات برمجة تطبيقات أخرى مثل هذا.
  • مكتبات .Net Standard 2.0 التي ترغب في استخدام Reflection.Emit لا يزال يتعين عليها استخدام حزم .Net Standard 1.x-style System. *.

سيتم حل هذه المشكلات إذا تمت إضافة إصدار .Net Standard 2.0 إلى حزم Reflection.Emit. هل هذا شيء يستحق فعله؟

على الرغم من أن كلاهما عبارة عن مراوغات صغيرة إلى حد ما ، إلا أنني لست متأكدًا من مقدار القيمة التي ستضيفها.

area-System.Reflection.Emit question

التعليق الأكثر فائدة

شكرا للجميع على ردود الفعل. استنادًا إلى التعليقات الهائلة ، أعدنا إدراج أحدث إصدار من الحزم الحالية:

https://www.nuget.org/packages/System.Reflection.Emit/4.3.0
https://www.nuget.org/packages/System.Reflection.Emit.Lightweight/4.3.0

ومع ذلك ، كما ذكرنا سابقًا في هذا الموضوع ، تدعي هذه الحزم أنها متوافقة مع netstandard1.1 ولكن هذه كذبة. سيعملون فقط على .NET Core و .NET Framework. لذلك إذا كنت تستهلكها من مكتبة netstandard ، فتوقع أن تفشل تلك المكتبة إذا تم تشغيلها على أي تطبيق .NET Standard آخر.

ونحن ما زلنا لا نملك حلا رائعا لدعم هذه على netstandard2.0 ولكن أصحاب (AtsushiKanjoshfree) من System.Relfection.Emit سيتم في محاولة لمعرفة الحل على المدى الطويل.

ال 58 كومينتر

ericstjweshaggard هل تعرف إذا كان عن قصد بهذه الطريقة، أو سهو؟

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

تضمين التغريدة

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

كيف لي أن أتعلم عن ذلك؟ بقدر ما أستطيع أن أقول ، لم يتم الإبلاغ عن Reflection.Emit من قبل Platform -omp. وعندما جوجل "انعكاس ينبعث صافي ستاندارد"، ويؤدي فقط على الصفحة الأولى تتحدث عن ما إذا كان يجب استخدامها بهذه الطريقة هو سقسقة من يوليو 2017 من قبلterrajobst مما يوحي بأن عليك أن تفعل ذلك (ربما تغير الوضع منذ ذلك الحين ؟).

سأترك terrajobst يرد على ذلك ، ربما كان يفكر في ميزة nuget gaurdrails التي كانت لدينا في حزم 1.x و 1.x. مع تلك التي لدينا تطبيقات غير مرتبة وبناء دعم الوقت للرسائل التي لا يتم دعم الأشياء. أنا لا أميل هنا بطريقة أو بأخرى فقط لشرح الطريقة التي تعمل بها الأشياء في الوقت الحالي. أعتقد أنه إذا تمكنا من الحصول على تسجيل الخروج من الأشخاص عند إضافة حزمة مع نظام أساسي غير مدعوم ، فيمكننا القيام بذلك.

FWIW: أي شيء متوفر في إطار عمل ولكنه ليس في معيار الشبكة أو في مكتبة / حزمة بها أصل قياسي يعني أنك بحاجة إلى استهداف إطار العمل للحصول عليه. هذا كل ما قصدته بتعليق توقعي.

تضمين التغريدة

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

ولكن هنا الحزمة (مع أصول .Net Standard 1.x) موجودة. لا أعتقد أنه يمكنك التوقف عن تحديث حزمة وافترض أن الناس لن يستخدموها بعد الآن. على الأقل ، يجب أن يكون لديك وثائق تشرح الموقف.

أكبر مشكلة في System.Reflection.Emit هي أنه ليس لدينا طريقة لتوفير المكتبة بطريقة قياسية بسبب TypeInfo (انظر https://github.com/dotnet/corefx/issues/14334). تستهدف الحزمة الحالية netstandard1.1 ولكنها كذبة وستعمل فقط على .NET Framework و .NET Core بسبب الاقتران الضيق الذي لدينا. لقد اخترقناها للعمل من خلال تشغيل حيل InternalsVisibleTo لمنحها إمكانية الوصول إلى منشئي TypeInfo ، ولكن هذه الحيلة نفسها هي التي تجعلها لا تعمل على منصة .NET Standard العامة. قررنا عدم نشر الخطأ أكثر من خلال اختراق netstandard2.0 بنفس الطريقة وبدلاً من ذلك توقفنا عن إنتاج الحزمة وجعلها منصة خاصة.

نشكرك على إثارة المشكلة svick ويجب علينا استخدام هذه المشكلة لتوثيق المشكلة في الحزمة.

ماذا عن إلغاء إدراج الحزم التي لم تعد محدثة على NuGet لذلك من الواضح أنها غير موصى بها؟

هذا اقتراح معقول. لقد ألغيت للتو جميع إصدارات https://www.nuget.org/packages/System.Reflection.Emit/ و https://www.nuget.org/packages/System.Reflection.Emit.Lightweight

هذا مطلوب جدا. عدم القدرة على إنشاء التجميعات وحفظها هو حاليًا أكبر مانع لـ dotnet / corefx # 1 الخاص بي للتحديث إلى .NET Core ، وأود حقًا أن أرى أن الحصول على واجهة برمجة التطبيقات الأساسية للغاية هذه قد جعلها أولوية أعلى من العمل على ميزات جديدة .

masonwheeler لمجرد الاتصال ، يمكنك استخدام Reflection.Emit إذا كنت تكتب تطبيقًا أو مكتبة .NET Core ، فلا يمكنك استخدامها أثناء كتابة مكتبة .NET Standard حاليًا.

weshaggard هل أنت متأكد؟ لقد تحققت للتو من الريبو ، ويبدو أنه لم يتم تنفيذ AssemblyBuilder.Save ، بل إنه غير موجود على الإطلاق في Core! (قد أكون مخطئًا ؛ فأنا على هاتفي ولا تكون واجهة الهاتف المحمول الخاصة بـ GitHub هي الأفضل ، ولكن هذا ما يبدو عليه).

masonwheeler أنت محق في أننا لا ندعم AssemblyBuilder. https://github.com/dotnet/corefx/issues/4491.

ذلك هو! اعتقدت أنني رأيت هذه المشكلة من قبل ، لكن البحث أظهر هذه المشكلة فقط. : ص

لكن نعم. بدون القدرة على إصدار نتائجك فعليًا ، لا يمكنك حقًا القول أنه يمكنك استخدام Reflection.Emit on Core. ☹️

weshaggard قبل حزمة System.Reflection.Emit.Lightweight كونها غير مدرجة على nuget.org كان من الممكن الحصول على حزمة Selenium.WebDriver في PowerShell 5 (لـ .Net Framework) و PowerShell Core 6 (لـ .Net Core 2.0) على نظام التشغيل Windows 10 باستخدام الأمر التالي: Install-Package Selenium.WebDriver -Destination $ PSScriptRoot -Force -ForceBootstrap

الآن لا يمكن لهذا الأمر تنزيل جميع تبعيات حزمة السيلينيوم لكلا إصداري PowerShell. فشل لأن حزمة System.Reflection.Emit.Lightweight.4.3.0 غير مدرجة على nuget.org.
خطأ: حزمة التثبيت: تعذر العثور على الحزمة (الحزم) التابعة (System.Reflection.Emit.Lightweight)

هل يمكنك تقديم النصيحة حول كيفية إصلاح هذه المشكلة؟

SergeyKhutornoy هل تستدعي "Install-Package" في VS من وحدة تحكم مدير الحزم؟ إذا كان الأمر كذلك ، فإن ذلك يثبت الحزمة بشكل صحيح بالنسبة لي. إذا كنت تتصل بـ Install-Package من Powershell ، فهذا نوع مختلف من إدارة الحزم. لقد جربت ذلك محليًا للتو وحصلت على خطأ مختلف (حزمة التثبيت: لم يتم العثور على تطابق لمعايير البحث المحددة واسم الحزمة "Selenium.WebDriver".) لست على دراية بنظام إدارة الحزم هذا ، لذا فأنا لست متأكدًا من كيفية التغلب عليه. شيء واحد يمكنك تجربته هو تثبيت System.Reflection.Emit.Lightweight 4.3.0 أولاً ثم معرفة ما إذا كان يعمل. إذا لم ينجح ذلك ، فهل هناك سبب لعدم تمكنك من استخدام أدوات VS أو nuget لتثبيت الحزمة؟

يعد إلغاء إدراج هذه الحزمة خطأ ، وعدم توفير إصدار .NET Standard 2.0 يعد خطأ.

نحن على وشك شحن إصدار رئيسي جديد من منتجنا ، NServiceBus ، ونستهدف netstandard2.0 . لدينا أيضًا اعتماد على System.Reflection.Emit و System.Reflection.Emit.Lightweight. كنت أنوي في الأصل استهداف .NET Framework و .NET Core بشكل منفصل ، لكن محادثة على Twitter مع netstandard2.0 بدلاً من ذلك.

لا أمانع في عدم قدرتي على حفظ التجميعات الديناميكية كثيرًا - يمكنني دائمًا اختبار المنطق في .NET Framework TFM - ولكن DynamicMethod مفيد بشكل لا يصدق ويستخدم على نطاق واسع جدًا لإنشاء مجموعات انعكاسية ومندوبي التحويل وما إلى ذلك حزم. System.Reflection.Emit. * لديها ما يزيد عن 20.000.000 عملية تنزيل.

يرجى إعادة طريقة للإشارة إلى DynamicMethod في مكتبات netstandard2.0.

كيف نستخدم DynamicMethod في .NET Core الآن بعد أن أصبح غير مدرج كحزمة؟

danielcrenna لست بحاجة إلى الحزمة لاستخدام DynamicMethod على .Net Core ، نظرًا لأنها مضمنة . ما عليك سوى استخدام الحزمة على .Net Standard.

أنا يمكن بناء بلدي وقت التشغيل (الذي صدر بالفعل) على .netstandard 2.0 باستخدام System.Reflection.Emit.Lightweight 4.3 كما يمكنني استخدام DynamicMethod. أرى الآن أن عملية الإنشاء تسحب الحزمة من ذاكرة التخزين المؤقت غير المتصلة وليس من nuget. ~ إذا تم غلق ذاكرة التخزين المؤقت غير المتصلة بالإنترنت ، فلا يمكنني إنشاء الكود مرة أخرى لـ .NETstandard. ~ (يؤدي إغلاق ذاكرة التخزين المؤقت إلى جعل عملية الإنشاء تسحب الحزمة مرة أخرى ، نظرًا لأن الحزمة لا تزال موجودة ، وإن كانت غير مدرجة ، لذا فهي ليست أداة عرض من الناحية الفنية. على الرغم من ذلك).

انظر هنا: https://apisof.net/catalog/System.Reflection.Emit.DynamicMethod ما هي النتيجة التي يجب أن أتخذها؟ هل هذا موجود في NS1.6؟ أو في بعض الأبعاد البينية حيث تكون "امتدادات النظام الأساسي" صالحة؟

إذن iow: عندما أستهدف .netstandard2.0 وأستخدم DynamicMethod ، يمكنني الإشارة إلى System.Reflection.Emit. خفيف الوزن على الرغم من أنه غير مدرج ، ومدعوم في ns1.6 (؟) ، لكن هذا يبدو حقًا غير مألوف: إنه شعور مسؤولية لأنني الآن أعتمد على حزمة غير مدرجة (وبعد ذلك يجب أن آمل أن يتم الاحتفاظ بالحزم غير المدرجة هناك حتى نهاية الوقت.) الشيء المحزن هو: لا يوجد بديل سوى الاعتماد على حزمة غير مدرجة وهذا ممكن فقط لأن واحدًا يعرف الاسم الدقيق.

// terrajobst

للإضافة: يعتمد EF Core 2.1 على Castle.Core (https://www.nuget.org/packages/Castle.Core/) لوكلائه ، والذي يعتمد على System.Reflection.Emit.

أليس من الحكمة لجميع المعنيين الحصول على هذه الحزمة (و Emit.Lightweight) ليتم تجنيدهم ببساطة مرة أخرى؟

FransBouma بالمعنى الدقيق للكلمة ، فإن EF Core Proxies لديها التبعية ، وليس EF Core نفسها. لكنها فوضى على أي حال.

في الحقيقة _FirebirdClient_ له تبعية على _System.Reflection.Emit_. وماذا تفعل الآن ، أليس كذلك؟

في حين أنه من المفهوم أن منصات AOT الكاملة لا يمكنها السماح بإنشاء أنواع جديدة في وقت التشغيل ، إلا أنه من المفاجئ أننا لا نستطيع دعم System.Reflection.Emit.Lightweight على هذه الأنظمة الأساسية.
LambdaExpression.Compile() عبر جميع الأنظمة الأساسية حتى لو تم تفسيره على AOT.

أنا مؤلف مكتبة LightInject DI والتي تستخدم Reflection.Emit و DynamicMethod لإنشاء رمز في وقت التشغيل. كان كل هذا جيدًا حتى بدأت هذه المنصات الأخرى في الظهور. SilverLight و WinRT و iOS وما إلى ذلك. اذا مالعمل؟ ما فعلته هو "تقشير" DynamicMethod حتى تتم ترجمة أكواد التشغيل إلى تعبيرات. هناك نوع من العلاقة 1-1 بين أكواد التشغيل والتعبيرات بحيث لا يكون بهذه الصعوبة على الإطلاق.

ألق نظرة هنا على التنفيذ.
https://github.com/seesharper/LightInject/blob/a01be40607761d9b446dc4acad37d7f717742975/src/LightInject/LightInject.cs#L4483

لاحظ أنني لا أنفذ جميع أكواد التشغيل. فقط تلك التي أحتاجها.

نقطتي هي أنه يجب أن يكون من الممكن القيام بذلك لجميع أكواد التشغيل ثم تمكين الكثير من المكتبات لاستهداف netstandard2.0. معظم المكتبات التي تستخدم Reflection.Emit لا تولد أنواعًا جديدة. يقومون ببساطة بإنشاء رمز من خلال DynamicMethod

لاحظ أيضًا أن DynamicProxy و Moq والمكتبات الأخرى التي تنشئ أنواعًا في وقت التشغيل لا يمكنها استهداف netstandard2.0 . يجب أن يكونوا netcoreapp لأنهم يعتمدون بشكل أساسي على AssemblyBuilder مع الأصدقاء
لذا فإن خلاصة القول هي أنه لا يمكن إزالة الحزمة System.Reflection.Emit.Lightweight من NuGet بالكامل كـ netstandard2.0 . ستكون هذه قصة LeftPad مرة أخرى

سنتى

هناك في مكان ما قائمة TFMs التي لا تدعم System.Reflection.Emit ؟ لقد أضفت للتو وحدات TFM صريحة net45 و netcoreapp2.0 إلى مشروعي ، لكنني متأكد من أنني أفتقد بعضها.

jbogard يجب أن تكون جميع

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

تشير ServiceStack إلى حزم Reflection.Emit التي تم حذفها الآن في ServiceStack.Text وهي حزمة التبعية الأساسية المستخدمة كل حزمة ServiceStack NuGet بالإضافة إلى العديد من حزم NuGet الأخرى التي تستخدمها كعنصر تبعية. نحن نقدم فقط إنشاءات netstandard2.0 و net45 ، مما يؤدي إلى إجبار النظام الأساسي netcore على كسر كل تبعية واحدة وكل مشروع netstandard2.0 يستخدمه - أي إطار العمل المستهدف المفضل لإنشاء منصة مشتركة يبني تدعم كلاً من .NET Framework و .NET Core.

إذن ما هي التوصية الآن للحزم التي تستخدم Reflection.Emit؟ التوقف عن نشر إصدارات .NET Standard 2.0 وإخبار الجميع أنه لم يعد بإمكانهم إنشاء إصدارات .NET Standard 2.0 لمكتباتهم ومشاريعهم؟

كان الحل السابق لاستخدام NET Standard APIs التي لا تنفذ واجهة برمجة التطبيقات هو طرح استثناءات وقت تشغيل PlatformNotSupportedException ، فلماذا بالضبط ليس هذا هو الحل هنا؟

seesharper نعم ، لقد أضفت هؤلاء ولكن هذا قد قائمة مستندات API أكثر ولكن ما الذي قد يكون مفقودًا؟ هل هذه قائمة شاملة من TFMs الممكنة التي تدعم واجهة برمجة التطبيقات؟ ماذا عن ، على سبيل المثال ، xamarinxboxone ؟

لقد قمت بإعادة هيكلة كود DynamicMethod / ILGenerator الخاص بي الذي استخدمته لإصدار طرق الضبط للخصائص في وقت التشغيل باستخدام حل Lambda.Compile () وبالتالي فقد الاعتماد على الانعكاس. التي كنت أرغب في إنفاقها على أشياء أخرى. ولكن للأسف ، هذه هي الحياة عندما "تتحرك الأشياء بسرعة وتنكسر كثيرًا" على ما أعتقد؟

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

أتفق تمامًا مع mythz والآخرين هنا ، لقد تم التواصل بشكل سيئ ، ومع 22 مليون تنزيل كان هذا قرارًا سخيفًا له عواقب بعيدة المدى.

mythz لا أعرف كيف تستخدمه ، ولكن بالنسبة إلى أشيائي ، كان عليّ الرجوع إلى علامات #if المميزة لإزالة الوظائف في الأنظمة الأساسية التي لا تدعم أنواع البناء أثناء التنقل (في مكتبتي ، قادرًا على التعيين إلى واجهة وأنشئ وكيلًا سريعًا).

jbogard نستخدم علامة منطقية Env.SupportsEmit لتحديد وقت التشغيل ما إذا كانت المنصة تدعم Reflection.Emit ، إذا كانت تستخدمه ، وإلا فإننا نعود إلى التعبيرات المجمعة. في هذه الملاحظة ، سيكون من المفيد وجود علامة Platform.SupportsEmit يمكن للجميع استخدامها للتحقق مما إذا كان النظام الأساسي قيد التشغيل يدعم Reflection.Emit.

سيتطلب التوجيه #if إنشاء العديد من تصميمات النظام الأساسي والتي قد تكون سبب التغيير الفاصل لجميع الحزم والمشاريع التابعة التي تستهدف .netstandard2.0 ، لأنها تتطلب أيضًا تبعيات .netstandard2.0 .

لمزيد من المناقشة فقط ، أود التأكد من أننا جميعًا على نفس الصفحة عندما يتعلق الأمر بالفرق بين System.Reflection.Emit و System.Reflection.Emit.Lightweight .

كان يجب في الواقع تقسيم هذه المشكلة إلى مشكلتين منفصلتين. 😄

  • هل يجب أن يكون هناك إصدار .Net Standard 2.0 من Reflection.Emit؟
  • هل يجب أن يكون هناك إصدار .Net Standard 2.0 من System.Reflection.Emit.LightWeight؟

النظام ، التفكير

تحتوي هذه الحزمة على AssemblyBuilder والفئات ذات الصلة التي نحتاجها لإنشاء تجميعات / أنواع في وقت التشغيل.
تكمن مشكلة هذه الحزمة في أنه لم يكن يجب وضعها على NuGet أبدًا كحزمة netstandard نظرًا لأن إنشاء أنواع جديدة في وقت التشغيل لا يمكن دعمه على منصات AOT الكاملة.
تخميني هو أن Microsoft أضافت هذا كحزمة netstandard لتسهيل الترحيل من الإطار الكامل إلى مكتبات .Net Core و netstandard . في الإدراك المتأخر ليست في الحقيقة أفضل فكرة.
نهج "الطعم والتبديل" (يفهمه مثل 5 أشخاص في العالم كله) ليس حلاً رائعًا أيضًا.

النظام ، التفكير ، الوزن ، الوزن الخفيف

تحتوي هذه الحزمة على DynamicMethod الذي يجعل من الممكن ترجمة التعليمات البرمجية ديناميكيًا دون إنشاء أنواع جديدة. "الطريقة الديناميكية" هي في الأساس طريقة ثابتة يمكننا من أجلها إنشاء مفوض يستخدم لاستدعاء الطريقة.
LambdaExpression.Compile هو في الأساس نفس الشيء وإذا نظرنا إلى التنفيذ في الإطار الكامل ، فسنرى أنه يستخدم بالفعل DynamicMethod تحت الأغطية
الشيء هو أن LambdaExpression.Compile() يعمل عبر جميع الأنظمة الأساسية باستخدام الترجمة الفورية على AOT. لهذا السبب ، لا يوجد سبب يمنعنا من إنشاء حزمة System.Reflection.Emit.LightWeight netstandard باستخدام التقنية التي وصفتها سابقًا في هذا الموضوع.

أعتقد أن سبب التراجع عن هذا الآن هو التأكد من أن المعيار يعطي في الواقع أي معنى في المستقبل. المشكلة كما أراها هي أننا قد نرى حزم مكتبة تستهدف netcoreapp بدلاً من netstandard وهذا سيكون سيئًا حقًا عندما يتعلق الأمر بتطوير المفهوم الكامل لـ netstandard .

اقتراحي هو بذل جهد لنشر System.Reflection.Emit.LightWeight كحزمة حقيقية netstandard ومواصلة الدفع مقابل netcoreapp عندما يتعلق الأمر بـ System.Reflection.Emit .

seesharper على حد علمي ، يستخدم Reflection.Emit (بما في ذلك Reflection.Emit.Lightweight) في المقام الأول للأداء. ولكن إذا قمت بتطبيق Reflection.Emit. lightweight باستخدام مترجم IL ، فمن المحتمل أن يكون أداؤه سيئًا للغاية. لذلك أنا لست مقتنعًا بالجهود المبذولة لدعم وضع تفسير IL في Reflection. ربما يكون الوزن الخفيف مبررًا.

من الغريب أيضًا أن System.Reflection.Emit.ILGenerator لا يزال مدرجًا (https://www.nuget.org/packages/System.Reflection.Emit.ILGeneration) ، نظرًا لأنه حزمة netstandard 1.6 ، ومع ذلك فإن ILGenerator لا يحتوي على تطبيق UWP (https://apisof.net/catalog/System.Reflection.Emit.ILGenerator).

آيو: القليل من الفوضى ، أليس كذلك؟

seesharper اقتراح جيد.

svick لا أعتقد أن هذا مبرر كافٍ قاعدة جرينسبون العاشرة ) ، ومن الأفضل ألا يضطر كل كاتب إلى اختراع وكتابة مترجمه (باستخدام انعكاس منتظم و Invoke ). إذا كان مكونًا قياسيًا ، فسيتم التخفيف على الأقل من الأجزاء "المحددة بشكل غير رسمي والمليئة بالأخطاء" من القاعدة. أما بالنسبة لأداء تطبيق استهداف AOT ، فلا يجب أن يكون مترجمًا لـ IL. حتى في الأنظمة الأساسية التي لا تسمح لعملية ما بإنشاء صفحات ذاكرة قابلة للتنفيذ ، يمكن للمرء تجميع طرق ديناميكية إلى تعليمات برمجية مترابطة مثل العديد من تطبيقات FORTH ، وللأساليب الديناميكية الصغيرة حيث يتناسب "جسم الطريقة" مع سطرين من ذاكرة التخزين المؤقت ، يجب أن يكون وقت التشغيل الزائد منخفضًا جدًا.

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

تعارض. تدعمها منصات .NET Core و .NET Framework الرئيسية ، فقط لأن بيئات AOT لا يجب أن تمنعها من دعم منصات .NET الرئيسية التي تستهدف netstandard2.0 .

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

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

كان الحل الأفضل هو الحل الحالي (خاصةً حيث أن إزالته الآن يعد تغييرًا مزعجًا وكاسحًا في أقسامه المتعدية) مما يتيح لنا استخدام Reflection. . تعني إزالة القدرة على استخدام Reflection.Emit في .NET Standard أن المكتبات التي تستخدمها لم يعد بإمكانها استهداف .NET Standard. ما هي النقطة المهمة أيضًا إذا لم نتمكن من استخدام الميزات التي يشاركها .NET Core و .NET Framework في تجريد لا يعتمد على النظام الأساسي؟ سيكون مجرد إضافة تجريدات غير ضرورية / ارتباك / تعقيد إلى نظام .NET البيئي دون أي فوائد.

شكرا للجميع على ردود الفعل. استنادًا إلى التعليقات الهائلة ، أعدنا إدراج أحدث إصدار من الحزم الحالية:

https://www.nuget.org/packages/System.Reflection.Emit/4.3.0
https://www.nuget.org/packages/System.Reflection.Emit.Lightweight/4.3.0

ومع ذلك ، كما ذكرنا سابقًا في هذا الموضوع ، تدعي هذه الحزم أنها متوافقة مع netstandard1.1 ولكن هذه كذبة. سيعملون فقط على .NET Core و .NET Framework. لذلك إذا كنت تستهلكها من مكتبة netstandard ، فتوقع أن تفشل تلك المكتبة إذا تم تشغيلها على أي تطبيق .NET Standard آخر.

ونحن ما زلنا لا نملك حلا رائعا لدعم هذه على netstandard2.0 ولكن أصحاب (AtsushiKanjoshfree) من System.Relfection.Emit سيتم في محاولة لمعرفة الحل على المدى الطويل.

svick

بقدر ما أعرف ، Reflection.Emit (بما في ذلك Reflection.Emit.Lightweight) يستخدم في المقام الأول للأداء. ولكن إذا قمت بتطبيق Reflection.Emit. lightweight باستخدام مترجم IL ، فمن المحتمل أن يكون أداؤه سيئًا للغاية. لذلك أنا لست مقتنعًا بالجهود المبذولة لدعم وضع تفسير IL في Reflection. ربما يكون الوزن الخفيف مبررًا.

أفهم أن LambaExpression.Compile() وتنفيذه يتم تفسيره على منصات AOT ، وبالتالي لا ينبغي أن يكون الأمر أسوأ عند القيام بذلك مقابل System.Reflection.Emit.LightWeight .
هناك الكثير من المكتبات التي تستخدم هذه الحزمة ووجود حزمة netstandard2.0 "حقيقية" من شأنه أن يتيح فجأة تشغيل هذه الحزم على جهاز iPhone الخاص بك دون إجبار مطوري هذه الحزم على إعادة كتابة التعليمات البرمجية الخاصة بهم لمطابقة الأنظمة الأساسية المختلفة. سينخفض ​​الأداء ، لكنه سيعمل تمامًا كما هو الحال اليوم مع LambdaExpression.Compile()

تضمين التغريدة

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

IMHO ، طرح PlatformNotSupportedException هو مجرد مظهر آخر لمجموعة API الفرعية التي رأيناها مع PCL. كما هو الحال مع System.Reflection.Emit.LightWeight ، يمكننا بالفعل تنفيذه وليس هناك سبب لرمي PlatformNotSupportedException . ومع ذلك ، أوافق على أنه من الصعب أن تقيد المنصات الأقل قدرة المعيار من المضي قدمًا. لكن هذا نوع من طبيعة وجود معيار. عند إجراء إضافات على المعيار ، يجب التأكد من إمكانية تنفيذه بطريقة ما على الأقل من خلال الأنظمة الأساسية التي تطبق المعيار. على الأقل بين اللاعبين الرئيسيين ويمكن القول أن Xamarin يناسب هذه الفئة.

هذا الرقم كما هو عليه اليوم هو نوع من الكذبة كما أراها. يدعي Xamarin أنه يدعم netstandard ، لكن هذا الدعم مليء بالاستثناءات التي قد تبدو معقولة بالنسبة لنا. بالنسبة للمبتدئين ، قد لا يكون من السهل فهمه.

image

تضمين التغريدة

الاستمرار في نشر System.Reflection.Emit netstandard كحزمة System.Reflection.Emit . لكنني أفضل استهداف netcoreapp على الكذب على المستهلك بأن هذه المكتبة يمكن تشغيلها في كل مكان.

تضمين التغريدة

IMHO ، رمي PlatformNotSupportedException هو مجرد مظهر آخر لمجموعة API الفرعية التي رأيناها مع PCL. كما هو الحال مع System.Reflection.Emit.LightWeight ، يمكننا بالفعل تنفيذه وليس هناك سبب لإلقاء PlatformNotSupportedException.

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

الاستمرار في نشر System.Reflection.Emit كحزمة قياسية ليس حلاً جيدًا على المدى الطويل. يجعل المعيار "خطأ" مرة أخرى ويجب أن يكون متاحًا فقط لـ net / netcoreapp.

يُعد فرض الإنشاءات الخاصة بالمنصة والاعتماد عليها نتيجة أسوأ بكثير ، خاصةً. مع العديد من التبعيات المتعدية التي تعتمد عليها بالفعل. تتمثل الميزة الأساسية لـ .NET Standard في القدرة على إنشاء مكتبات ومشاريع لاستهداف تجريد واحد مفيد ، إذا لم نتمكن من استخدامه للوصول إلى الميزات الرئيسية المتوفرة في .NET Core و .NET Framework ، فإنه يفشل في حل استخدامه الأساسي -حالة وقد لا تكون موجودة أيضًا نظرًا لأنها تضيف المزيد من التجريدات / الارتباك إلى نظام .NET البيئي دون أي فوائد على PCLs.

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

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

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

تضمين التغريدة

ونحن ما زلنا لا نملك حلا رائعا لدعم هذه على netstandard2.0 ولكن أصحاب (AtsushiKanjoshfree) من System.Relfection.Emit سيتم في محاولة لمعرفة الحل على المدى الطويل.

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

mythz أنت على حق تماما.

تضمين التغريدة

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

ومع ذلك ، فقد حددت تعليقك على أنه "مسيء" لأنه ليس بناءً. لن يؤدي إهانة الناس إلى معالجة هذه المشكلات. ضع في اعتبارك أيضًا أن هذه ليست سياسة نتحكم فيها. إن حقيقة أنه لا يمكنك إنشاء التعليمات البرمجية وتنفيذها في وقت التشغيل على نظام التشغيل iOS هو قرار سياسي من قبل Apple. أيضًا ، في بعض الحالات ، لا يكون هذا تقييدًا للسياسة ولكنه تقني.

هناك ثلاثة خيارات مع انعكاس انبعاث:

  1. إصلاح الحزم الحالية وجعلها تعمل فوق .NET Standard 2.0 . المشكلة هي علاقة توريث غريبة بين Type و TypeInfo في .NET Standard 1.x مقارنة بـ 2.0 ووجود منشئات غير عامة. يمكنني الخوض في مزيد من التفاصيل ، ولكن من أجل جعل الحزمة قابلة للبناء فعليًا دون استعادة الاختراقات ، فهذا أمر صعب بعض الشيء ، وهذا هو السبب في أننا قررنا في الأصل إخفاء الحزم.

  2. أضف الانعكاس المنبعث إلى .NET Standard vNext . من أجل دعم سيناريوهات AOT فقط ، من المحتمل أن يتضمن ذلك واجهة برمجة تطبيقات ذات قدرة تسمح للمستهلكين بالتحقق مما إذا كان إنشاء الكود مدعومًا أو فعالاً (أي ما إذا كنا نستخدم التنفيذ الحقيقي بدلاً من التفسير).

  3. عدم تعريض الانعكاس المنبعث إلى .NET Standard ويتطلب مؤلفي المكتبة أهدافًا متعددة . كان هذا هو المسار الأصلي عندما بدأنا بإخفاء الحزمة.

في الوقت الحالي ، نحن نميل إلى الخيار الأول ولكن الخيار الثاني موجود أيضًا على الطاولة.

أنا أؤيد 2. إنها موجودة في كل مكان بما يكفي لتكون موجودة. نحن بحاجة إلى التحقق من القدرة على أي حال لأسباب أخرى.

أنا أؤيد 2. إنها موجودة في كل مكان بما يكفي لتكون موجودة. نحن بحاجة إلى التحقق من القدرة على أي حال لأسباب أخرى.

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

لذلك أنا أفكر في إصلاح بسيط لجعل هذه الحزم تعمل كما هي ولكن أيضًا إصلاح .NET Standard 2.0 vNext.

terrajobst هل هناك شيء بخصوص الخيار 1 يجعل عمل الخيار الثاني أكثر صعوبة؟ يبدو لي أن الحصول على نسخة من الحزم التي تستهدف netstandard2.0 بدلاً من الحاجة إلى سحب الرسم البياني للحزمة netstandard1.1 سيكون هدفًا جيدًا على المدى القصير. ثم بالنسبة لـ vNext of the standard ، يمكن أن يصبح جزءًا منه ، ولن تحتاج إلى الحزم بعد الآن.

لذا ، ما لم يكن هناك سبب وجيه حقًا لعدم القيام بذلك ، أصوت لكل من 1 و 2.

bording

يبدو أننا نشرنا افتراضيًا في نفس الوقت. آمل أن يتناول تعليقي سؤالك :-)

الرجاء ملاحظة أن netstandard2.0 يدعم الأسلوب الثابت System.Reflection.Assembly.Load(byte[] rawAssembly) ، والذي يقوم بتحميل تجميع من مصفوفة بايت صور ثنائية. هذا يعني أنه من الممكن تنفيذ ليس كل ما عدا معظم واجهات برمجة التطبيقات APIs System.Reflection.Emit تحت netstandard2.0 .

(عذرًا ، لا أعرف عدد الأنظمة الأساسية التي تدعم Assembly.Load بدون PNSE)

GlassGrass ما هي أطر العمل التي تتخيل أن تطبيق netstandard2.0 سيطبق عليها؟

يمكنني بالتأكيد أن أتخيل بعض التنفيذ الذي من شأنه أن يكتب IL وينتج تجميعًا مثل ILASM الذي يحركه API ، لكنني لا أرى الأطر الحالية حيث أرغب في استخدام ذلك.

يمكن أيضًا أن تدعم الأطر التي تحتوي على JIT (وتدعم Assembly.Load) Ref.Emit مباشرةً ، وتوفر تطبيق Ref.Emit بدلاً من إصدار netstandard2.0. أعلم أن هذا هو الحال على الأقل لسطح المكتب / .netcore / .netnative. الأولين يدعمان ref.emit ويوفران تنفيذًا ، والأحدث لا يحتوي على JIT ولا يدعم تحميل التجميع الديناميكي.

أعتقد أنه سيكون مشروعًا مثيرًا للاهتمام لشخص ما أن يتجول في corefxlab لكتابة شيء ما فوق System.Reflection.Metadata يبدو مثل Ref.Emit (أو أفضل). لست متأكدًا مما إذا كان أي شخص ينظر إلى ذلك بالفعل. تضمين التغريدة

أعتقد أنه سيكون مشروعًا مثيرًا للاهتمام لشخص ما أن يتلاعب في corefxlab لكتابة شيء ما فوق System.Reflection.Metadata الذي يشبه المرجع Emit (أو أفضل).

هذا على لوحتي: (https://github.com/dotnet/corefx/issues/4491 و https://github.com/dotnet/corefx/issues/2800)

سيأتي https://github.com/dotnet/corefx/issues/2800 أولاً حيث من المحتمل أن تكون الأشياء التي يصدرها المرجع امتدادًا لها. لقد بدأت في إنشاء نماذج 2800 هذا الأسبوع وسأواصل هذا العمل في الأشهر المقبلة. لن أقوم بنقلها إلى corefxlab حتى أكون أكثر طولاً. سير العمل غير فعال للغاية هناك بالنسبة لذوقي.

AtsushiKan :

لقد ذكرت ما يلي في مكان آخر سابقًا: أحد الأشياء التي لا يمكن أن يقوم بها System.Reflection.Metadata و Assembly.Load(byte[]) هو الانبعاث التدريجي لكل نوع. لا يمكنك إصدار نوع واحد ، ثم نوع آخر ... يمكنك فقط إرسال تجميعات كاملة ، مما يعني أن هذا ليس مفيدًا للغاية ، على سبيل المثال ، للمكتبات الساخرة التي تعتمد على إنشاء نوع وكيل ديناميكي.

بالطبع يمكن للمرء فقط إنتاج تجميعات من نوع واحد ، ولكن من المحتمل أن يصبح هذا غير فعال وصعبًا عند جعل الأجزاء الداخلية مرئية للتجمعات التي تم إنشاؤها ديناميكيًا عبر [assembly: InternalsVisibleTo] (شيء آخر يتطلبه غالبًا ما تتطلبه مكتبات الاستهزاء / الاختبار). يجب أن تكون قادرًا على إعطاء العديد من التجميعات الديناميكية أحادية النوع نفس الهوية / الاسم القوي حتى يعمل هذا. (قد يسمح وقت التشغيل بالفعل بهذا عمليًا ، لكن لا يمكنني العثور على وثائق تؤكد ذلك رسميًا.)

stakx يمكنك إرسال System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute إلى التجميع الديناميكي للسماح له بالوصول إلى الأعضاء غير العموميين للتجميع المحدد ، بدلاً من استخدام IVT.

@ طمات : هذا مثير للاهتمام. هل هذه السمة موثقة رسميًا في مكان ما؟

إنه لأمر مؤسف أن هذه السمة الخاصة غير موثقة رسميًا ، مما يجعلها نوعًا من المقامرة لاستخدامها خارج وقت التشغيل.

هل يضاف هذا إلى .NET core 3.0 ؟

تضمين التغريدة

karelz https://github.com/dotnet/corefx/issues/30654 يتتبع العمل لـ 3.0

@ joshfree هل هذا خداع أم أنه يغطي أكثر؟

karelz لقد غطت المشكلة مع حذف حزمة Ref.Emit بشكل غير صحيح من nuget ثم إعادة إدراج الحزمة بواسطةweshaggard. أعتقد أنه يمكن الآن إغلاق هذه المشكلة حيث يتم تعقب العمل المتبقي باستخدام dotnet / corefx # 30654.

حسنًا ، سيتم الإغلاق ثم :) ... يتم تتبع العمل المتبقي في dotnet / corefx # 30654 كما ذكر أعلاه.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات