Runtime: Reflection.Emitの.NetStandard 2.0バージョンが必要ですか?

作成日 2018年04月27日  ·  58コメント  ·  ソース: dotnet/runtime

System.Reflection.Emitは.NetStandardの一部ではありませんが、.Net Standardライブラリ(具体的には、 System.Reflection.EmitおよびSystem.Reflection.Emit.Lightweight )から使用できるパッケージがあります。 ただし、これらのパッケージには.Net Standard 2.0バージョンはなく、.Net Standard1.xバージョンのみが含まれています。

これにはいくつかの意味があります。

  • .Net Standard 2.0ライブラリはtypeBuilder.CreateType()使用できず(このコードは.Net Framework4.6.1と.NetCore 2.0の両方で機能しますが)、代わりにtypeBuilder.CreateTypeInfo().AsType()を使用する必要があります。 このような他のAPIもある可能性があります。
  • Reflection.Emitを使用する.NetStandard 2.0ライブラリは、引き続き.Net Standard1.xスタイルのSystem。*パッケージを使用する必要があります。

これらの問題は、.Net Standard2.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と互換性があると主張していますが、それは嘘です。 これらは、.NETCoreおよび.NETFrameworkでのみ機能します。 したがって、netstandardライブラリからそれらを使用している場合、他の.NET Standard実装で実行すると、ライブラリが失敗することが予想されます。

netstandard2.0でこれらをサポートするための優れたソリューションはまだありませんが、System.Relfection.Emitの所有者( @AtsushiKan @joshfree)は、より長期的なソリューションを見つけようとしています。

全てのコメント58件

@ericstj @weshaggardそれがこのように意図されているのか、それとも見落としなのか知っていますか?

それは意図的なものでした。 サポートがギザギザで、移植可能な実装がないこのようなライブラリについては、パッケージの出荷を停止しました。 必要に応じて、特定のフレームワークをターゲットにすることが期待されます。 一部の人には、地雷を含むパッケージを持ち帰りました(一部のプラットフォームで実装をスローします)。 人々は私たちがそれを追加することを提案することができましたが、特にこれはすべてのAOTベースの.netフレームワークでのサポートの欠如のために過去にいくつかの激しい議論がありました。 / cc @terrajobst

@ericstj

必要に応じて、特定のフレームワークをターゲットにすることが期待されます。

それについてどうやって学ぶのですか? 私の知る限り、Reflection.Emitはplatform-compatによって報告されていません。 そして、私が「リフレクションエミット.Netスタンダード」をグーグルで検索したときそれをそのように使うべきかどうかについて話している最初のページの唯一の結果はすべきだと示唆する@terrajobstによる2017年7月からのツイートです(おそらくそれ以来状況が変わった?)。

@terrajobstにそれに応答させます。おそらく、彼は1.xおよび1.xパッケージにあるnugetgaurdrails機能について考えていたのでしょう。 それらを使用して、実装がギザギザになり、サポートされていないメッセージングの時間サポートを構築しました。 ここでは、現在の状況を説明するだけで、特に傾いているわけではありません。 サポートされていない実装のプラットフォームでパッケージを追加し直すことについて、人々から承認を得ることができれば、そうすることができると思います。

フレームワークで利用可能であるが、netstandardまたはnetstandardアセットを含むライブラリ/パッケージにないものはすべて、フレームワークをターゲットにして取得する必要があることを意味します。 それが私の期待のコメントで私が意味したすべてです。

@ericstj

フレームワークで利用可能であるが、netstandardまたはnetstandardアセットを含むライブラリ/パッケージにないものはすべて、フレームワークをターゲットにして取得する必要があることを意味します。 それが私の期待のコメントで私が意味したすべてです。

ただし、ここにはパッケージ(.Net Standard 1.xアセットを含む)が存在します。 パッケージの更新をやめて、人々がそれをもう使用しないと想定することはできないと思います。 少なくとも、状況を説明するドキュメントが必要です。

System.Reflection.Emitの最大の問題は、TypeInfoが原因で、ネット標準の方法でライブラリを提供する方法がないことです(https://github.com/dotnet/corefx/issues/14334を参照)。 既存のパッケージはnetstandard1.1を対象としていますが、これは嘘であり、緊密な結合があるため、.NETFrameworkと.NETCoreでのみ機能します。 InternalsVisibleToトリックを実行して、TypeInfoのコンストラクターにアクセスできるようにすることで、ハッキングして機能させましたが、同じトリックが、一般的な.NETStandardプラットフォームで機能しない原因となっています。 同じ方法でnetstandard2.0をハッキングすることでエラーをさらに伝播しないことにし、代わりにパッケージの作成を停止してプラットフォーム固有にしました。

@svickの問題を提起していただきありがとうございます。この問題を使用して、パッケージの問題を文書化する必要があります。

更新されなくなったパッケージをNuGetでリストから外して、推奨されていないことは明らかです。

それは合理的な提案です。 https://www.nuget.org/packages/System.Reflection.Emit/https://www.nuget.org/packages/System.Reflection.Emit.Lightweightのすべてのバージョンのリストを

これは非常に必要です。 アセンブリをビルドして保存できないことは、現在、.NETCoreに更新するための私のdotnet / corefx#1最大のブロッカーです。この非常に基本的なAPIを高速化することを、新機能に取り組むよりも優先させたいと考えています。 。

@masonwheelerは、Reflection.Emitを使用できます。現在、.NET Coreアプリまたはライブラリを作成している場合は、

@weshaggardよろしいですか? リポジトリを確認したところ、 AssemblyBuilder.Saveまだ実装されていないだけでなく、Coreに

@masonwheelerは、別の問題https://github.com/dotnet/corefx/issues/4491によって追跡されているAssemblyBuilder.Save in .NETCoreをサポートしていないということです

そこにそれがある! 私は以前にその問題を見たことがあると思っていましたが、検索するとこれだけが見つかりました。 :P

しかし、ええ。 実際に結果を出力する機能がなければ、CoreでReflection.Emitを使用できるとは言えません。 ☹️

System.Reflection.Emit.Lightweightパッケージがnuget.orgで非公開になる前の@weshaggardは、Windows10のPowerShell5(.Net Frameworkの場合)およびPowerShell Core 6(.Net Core 2.0の場合)でSelenium.WebDriverパッケージを取得することができました。次のコマンドを使用します。Install-PackageSelenium.WebDriver-Destination$ PSScriptRoot -Force -ForceBootstrap

現在、このコマンドは、両方のPowerShellバージョンのすべてのSeleniumパッケージの依存関係をダウンロードすることはできません。 System.Reflection.Emit.Lightweight.4.3.0パッケージがnuget.orgにリストされていないため、失敗します。
エラー:インストールパッケージ:依存パッケージが見つかりません(System.Reflection.Emit.Lightweight)

この問題を修正する方法についてアドバイスをいただけますか?

@SergeyKhutornoyは、パッケージマネージャーコンソールからVSで「Install-Package」を呼び出していますか? もしそうなら、それは私のためにパッケージを正しくインストールします。 別の種類のパッケージ管理であるPowershellからInstall-Packageを呼び出す場合。 私は実際にそれをローカルで試したところ、別のエラーが発生しました(Install-Package:指定された検索条件とパッケージ名 'Selenium.WebDriver'に一致するものが見つかりませんでした)。私はそのパッケージ管理システムに精通していないので、それを回避する方法がわからない。 最初にSystem.Reflection.Emit.Lightweight4.3.0を明示的にインストールしてから、それが機能するかどうかを確認することをお勧めします。 それが機能しない場合は、VSまたはnugetツールを使用してパッケージをインストールできない理由がありますか?

このパッケージをリストから外すことは間違いであり、.NET Standard2.0バージョンを提供しないことは間違いです。

製品のメジャーな新バージョンであるNServiceBusを出荷しようとしており、 netstandard2.0をターゲットにしています。 System.Reflection.EmitとSystem.Reflection.Emit.Lightweightにも依存しています。 もともとは.NETFramework@ terrajobstとのTwitterの会話とこれらのパッケージの発見が利用可能であったため、計画を変更し、代わりにnetstandard2.0をターゲットにしました。

動的アセンブリをあまり保存できなくてもかまいません-.NETFramework TFMでロジックをいつでもテストできます-しかし、 DynamicMethodは非常に便利で、リフレクションサンクやコンバーターデリゲートなどを生成するために非常に広く使用されています.System.Reflection.Emit。*パッケージのダウンロード数は20,000,000を超えています。

netstandard2.0ライブラリでDynamicMethodを参照する方法を持ち帰ってください。

パッケージとしてリストにないので、.NET CoreでDynamicMethodをどのように使用しますか?

@danielcrenna .Net CoreでDynamicMethodを使用するためのパッケージは組み込まれているため、必要ありません。 .NetStandardで使用するために必要なのはパッケージだけです。

DynamicMethodを使用しているので、System.Reflection.Emit.Lightweight 4.3を使用して、.netstandard 2.0でランタイム(すでにリリースされています)を構築できます。 ビルドプロセスが、nugetからではなくオフラインキャッシュからパッケージをプルすることがわかりました。 〜オフラインキャッシュがホースで接続されている場合、.NETstandardのコードを再度ビルドすることはできません。〜(キャッシュをホースで接続すると、リストにない場合でもパッケージがまだ存在するため、ビルドプロセスでパッケージが再度プルされます。技術的には。意味的にはそうですが)。

ここを見てください: https

つまり、.netstandard2.0をターゲットにしてDynamicMethodを使用しているので、System.Reflection.Emit.Lightweightを参照できますが、リストにはなく、ns1.6(?)でサポートされていますが、これは本当に気分が悪いです。私は現在、非公開のパッケージに依存しているため、責任があります(そして、非公開のパッケージが時間の終わりまでそこに保持されることを期待する必要があります)。悲しいことに、非公開のパッケージに依存する以外に選択肢はありません。正確な名前を知っています。

// @terrajobst

追加:EF Core 2.1は、System.Reflection.Emitに依存するプロキシをCastle.Core(https://www.nuget.org/packages/Castle.Core/)に依存しています。

このパッケージ(およびEmit.Lightweight)を単に再度参加させることは、関係者全員にとって賢明ではありませんか?

@FransBouma厳密に言えば、EFコアプロキシには依存関係があり、EFコア自体には依存関係がありません。 しかし、とにかくそれは混乱です。

実際、_FirebirdClient_は_System.Reflection.Emit_に依存しています。 そして、今何をすべきでしょうか?

完全なAOTプラットフォームでは実行時に新しい型を生成できないことは理解できますが、これらのプラットフォームでSystem.Reflection.Emit.Lightweightをサポートできないことはさらに驚きです。
LambdaExpression.Compile()は、AOTで解釈された場合でも、すべてのプラットフォームで機能します。

私はLightInjectDIライブラリの作成者であり、実行時にコードを生成するためにReflection.EmitDynamicMethodを使用しています。 これらの他のプラットフォームが出現し始めるまで、これはすべて良かったです。 SilverLight、WinRT、iOSなど。 じゃあ何をすればいいの? 私がしたことは、OpCodeが式に変換されるように、 DynamicMethodを「シム」すること

実装については、こちらをご覧ください。
https://github.com/seesharper/LightInject/blob/a01be40607761d9b446dc4acad37d7f717742975/src/LightInject/LightInject.cs#L4483

すべてのオペコードを実装しているわけではないことに注意してください。 必要なものだけ。

私のポイントは、すべてのOpCodeに対してこれを実行してから、多くのライブラリが引き続きnetstandard2.0をターゲットにすることができるはずだということです。 Reflection.Emitを使用するほとんどのライブラリは、新しいタイプを生成しません。 DynamicMethodを介してコードを生成するだけです

また、実行時に型を生成するDynamicProxy、Moq、およびその他のライブラリは、 netstandard2.0ターゲットにできないことに注意してください。 彼らは基本的に友達とAssemblyBuilder依存しているので、彼らはnetcoreappなければなりません
つまり、 System.Reflection.Emit.Lightweightパッケージをnetstandard2.0としてNuGetから完全に削除することはできません。 それは再びLeftPadの話になります

私の2セント

サポートてTFMSのリストのどこかにありますSystem.Reflection.Emitnet45netcoreapp2.0明示的なTFMをプロジェクトに追加しましたが、いくつか欠けていると確信しています。

@jbogard netcoreapp TFMに加えて、すべてのフルフレームワークTFMが適切である必要があります。 これはAutoMapperにありますか?

これは、パッケージのダウンロード数が2,200万であることを考えると、影響を与えるコミュニティからの関与がほとんどないように思われる、広範囲にわたる結果を伴う、よく考えられて伝達されていない決定のようです。 それは、現在それに依存しているすべての人への潜在的な影響についてのある種の分析を正当化するのではないでしょうか?

ServiceStackは、ServiceStack.Text内のリストから除外されたReflection.Emitパッケージを参照しすべてのServiceStack NuGetパッケージ、およびそれを依存関係として使用する他のいくつかのNuGetパッケージでnetstandard2.0net45ビルドのみを提供します。.netcoreプラットフォームをターゲットにすると、すべてのnetstandard2.0プロジェクトが壊れます。 .NETFrameworkと.NETCoreの両方をサポートするビルド。

では、Reflection.Emitを使用するパッケージの現在の推奨事項は何ですか? .NET Standard 2.0ビルドの公開を停止し、ライブラリとプロジェクト用に.NET Standard 2.0ビルドを作成できなくなったことを全員に伝えますか?

APIを実装しない.NET標準APIを使用するための以前の解決策は、 PlatformNotSupportedExceptionランタイム例外をスローすることでしたが、なぜそれがここでの解決策ではないのですか?

@seesharperはい、私はそれらを追加しましたが、それは他のものを除外するかもしれません。 APIドキュメントにはさらに多くのリストがありますが、他に何が欠けている可能性がありますか? これは、APIをサポートする可能性のあるTFMの包括的なリストですか? たとえば、 xamarinxboxoneどうですか?

Lambda.Compile()ソリューションを使用して実行時にプロパティのセッターメソッドを発行するために使用したDynamicMethod / ILGeneratorコードをリファクタリングしたため、Reflection.Emitへの依存関係はなくなりましたが、3〜4時間を費やす必要がありました。他のことに費やしたかったのですが。 しかし、悲しいかな、それは物事が「速く動き、頻繁に壊れる」人生だと思いますか?

とにかく、私が少し気がかりなのは、過去数週間のこのスレッドでのマイクロソフトの担当者からの耳をつんざくような沈黙です。 実際に物事を変えることができる人がいないとき、部屋で物事を議論しているような気がします。

私はここで@mythzや他の人たちに完全に同意します、それは不十分に伝達されます、そして広範囲にわたる結果を伴うばかげた決定でした。

@mythz使用方法はわかりませんが、私の場合は、#if機能フラグに戻して、オンザフライで型の作成をサポートしていないプラットフォームの機能を削除する必要がありました(私のライブラリでは、インターフェイスにマップでき、その場でプロキシを作成します)。

@jbogard Env.SupportsEmitブールフラグを使用して、プラットフォームがReflection.Emitをサポートしているかどうかを実行時に決定します。サポートしている場合は、コンパイルされた式にフォールバックします。 その点で、実行中のプラットフォームがReflection.Emitをサポートしているかどうかを確認するために誰もが使用できるPlatform.SupportsEmitフラグがあると便利です。

#ifディレクティブでは、複数のプラットフォームビルドを作成する必要があります。これは、 .netstandard2.0依存関係も必要とするため、 .netstandard2.0を対象とするすべての依存パッケージとプロジェクトの重大な変更の原因になります。

さらなる議論のために、 System.Reflection.EmitSystem.Reflection.Emit.Lightweightの違いに関しては、私たち全員が同じページにいることを確認したいと思います。

この問題は、実際には2つの別々の問題に分割されているはずです。 😄

  • Reflection.Emitの.NetStandard 2.0バージョンが必要ですか?
  • System.Reflection.Emit.LightWeightの.NetStandard 2.0バージョンが必要ですか?

System.Reflection.Emit

このパッケージには、実行時にアセンブリ/タイプを生成するために必要なAssemblyBuilderと関連クラスが含まれています。
このパッケージの問題は、実行時に新しい型を生成することは完全なAOTプラットフォームではサポートできないため、 netstandardパッケージとしてNuGetに配置されるべきではなかったことです。
私の推測では、Microsoftはこれをnetstandardパッケージとして追加して、完全なフレームワークから.Net Coreおよびnetstandardライブラリへの移行を容易にしました。 後から考えると、本当に最良のアイデアではありません。
「おとり商法」アプローチ(全世界で5人のように理解されている)も、優れたソリューションではありません。

System.Reflection.Emit.LightWeight

このパッケージには、新しい型を作成せずにコードを動的にコンパイルできるようにするDynamicMethodが含まれています。 「動的メソッド」は基本的に静的メソッドであり、メソッドを呼び出すために使用されるデリゲートを作成できます。
LambdaExpression.Compileは基本的に同じものであり、完全なフレームワークでの実装を見ると、実際には内部でDynamicMethod使用していることがわかります。
重要なのは、 LambdaExpression.Compile()は、AOTの解釈を使用してすべてのプラットフォームで機能するということです。 このため、このスレッドで前に説明した手法を使用して、 netstandardあるSystem.Reflection.Emit.LightWeightパッケージを作成できない理由はありません。

私の推測では、これをバックトラックする理由は、標準が実際に将来何らかの意味を与えることを保証するためです。 私はそれが我々がターゲットライブラリパッケージ見るかもしれないということです見るように問題netcoreapp代わりにnetstandardと、それは全体のコンセプトの進化に来るときそれは本当に悪いだろうnetstandard

私の提案は、公開する努力することですSystem.Reflection.Emit.LightWeight真としてnetstandardパッケージ化とを推進していきnetcoreappそれがに来るときSystem.Reflection.Emit

@seesharper私の知る限り、Reflection.Emit(Reflection.Emit.Lightweightを含む)は主にパフォーマンスに使用されます。 ただし、ILインタープリターを使用してReflection.Emit.Lightweightを実装した場合、そのパフォーマンスはかなり悪くなる可能性があります。 したがって、Reflection.Emit.LightweightでIL解釈モードをサポートする努力が正当化されるとは確信していません。

System.Reflection.Emit.ILGeneratorがnetstandard1.6パッケージであるため、まだリストされている(https://www.nuget.org/packages/System.Reflection.Emit.ILGeneration)のも奇妙ですが、ILGeneratorにはUWPが実装されていません。 (https://apisof.net/catalog/System.Reflection.Emit.ILGenerator)。

Iow:少し混乱しましたか?

@seesharper良い提案。

@svickそれをカットするのに十分な理由ではないと思います。 ドメイン固有言語には、実行時にコードを構築する機能が必要です。 DSLは大規模なプロジェクト( Greenspunの10番目のルール)で十分頻繁に発生します。すべてのライターが独自のインタープリターを発明して作成する必要がない場合(定期的な反射とInvoke )の方が良いでしょう。 それが標準コンポーネントである場合、少なくともルールの「非公式に指定され、バグが多い」部分は軽減されます。 AOTターゲティングの実装のパフォーマンスに関しては、ILインタープリターである必要はありません。 プロセスが実行可能メモリページを作成することを許可しないプラットフォームでも、多くのFORTH実装が行うように、動的メソッドをスレッドコードにコンパイルできます。また、「メソッド本体」が2つのキャッシュラインに収まる小さな動的メソッドの場合、実行時のオーバーヘッドはかなり低くする必要があります。

このパッケージの問題は、実行時に新しい型を生成することは完全なAOTプラットフォームではサポートできないため、NuGetにnetstandardパッケージとして配置されるべきではなかったことです。

同意しない。 主要な.NETCoreおよび.NETFrameworkプラットフォームは、AOT環境が、 netstandard2.0を対象とする主要な.NETプラットフォームをサポートできることを妨げるべきではないという理由だけでそれをサポートします。

これは、今後の.NET Standardの戦略になりましたか? AOT環境でサポートされていないAPIは削除されますか? したがって、 PlatformNotSupportedException例外はなくなり、APIはヤンクされ、代わりにPCLサブセットに戻りますか? それとも、一貫性がなく、一部の機能のAPIサーフェスを選択的に削減し、他の機能を引き続き投入するのでしょうか。

最小公分母APIの共通部分をサポートすることは、PCLが行ったことであり、PCLのおとり商法を強制し、複数のプラットフォーム固有の実装に委任するという恐ろしい開発経験をもたらしました。これは、に移動したときに捨てたすべての投資です。 NET標準。

最善の解決策は、Reflection.Emitをサポートするすべてのプラットフォームで使用できる一方で、サポートしていないプラットフォームのフォールバックを実装する必要がある既存のソリューションでした(特に、現在削除すると、推移的な部門に破壊的で破壊的な変更が加えられます)。 。 .NET StandardでReflection.Emitを使用する機能を削除すると、それを使用するライブラリは.NETStandardをターゲットにできなくなります。 プラットフォームに依存しない抽象化で.NETCoreと.NETFrameworkが共有する機能を使用できない場合でも、何が重要なのでしょうか。 .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と互換性があると主張していますが、それは嘘です。 これらは、.NETCoreおよび.NETFrameworkでのみ機能します。 したがって、netstandardライブラリからそれらを使用している場合、他の.NET Standard実装で実行すると、ライブラリが失敗することが予想されます。

netstandard2.0でこれらをサポートするための優れたソリューションはまだありませんが、System.Relfection.Emitの所有者( @AtsushiKan @joshfree)は、より長期的なソリューションを見つけようとしています。

@svick

私の知る限り、Reflection.Emit(Reflection.Emit.Lightweightを含む)は主にパフォーマンスに使用されます。 ただし、ILインタープリターを使用してReflection.Emit.Lightweightを実装した場合、そのパフォーマンスはかなり悪くなる可能性があります。 したがって、Reflection.Emit.LightweightでIL解釈モードをサポートする努力が正当化されるとは確信していません。

LambaExpression.Compile()とその実行はAOTプラットフォームで解釈されるので、 System.Reflection.Emit.LightWeightそれを行うのは悪くないはずです。
このパッケージを使用しているライブラリはたくさんあり、「真の」netstandard2.0パッケージを使用すると、これらのパッケージの開発者がさまざまなプラットフォームに一致するようにコードを書き直すことなく、iPhoneでこれらのパッケージを突然実行できるようになります。 パフォーマンスは低下しますが、 LambdaExpression.Compile()た場合と同じように機能します。

@mythz

これは、今後の.NET Standardの戦略になりましたか? AOT環境でサポートされていないAPIは削除されますか? したがって、PlatformNotSupportedException例外はなくなり、APIはヤンクされ、代わりにPCLサブセットに戻りますか? それとも、一貫性がなく、一部の機能のAPIサーフェスを選択的に削減し、他の機能を引き続き投入するのでしょうか。

IMHO、 PlatformNotSupportedException投げることは、PCLで見たAPIサブセットのもう1つの現れです。 System.Reflection.Emit.LightWeightの場合と同様に、実際に実装でき、 PlatformNotSupportedExceptionをスローする理由はありません。 ただし、能力の低いプラットフォームが標準の前進を制限することは問題があることに同意します。 しかし、それは一種の基準を持つという性質です。 標準に追加が行われる場合、標準を実装するプラットフォームによって少なくとも何らかの方法で実装できることを確認する必要があります。 少なくとも主要なプレーヤーの間では、Xamarinはそのカテゴリに当てはまると言えます。

今日のこの姿は、私が見ているように一種の嘘です。 Xamarinはnetstandardをサポートすると主張していますが、そのサポートには、私たちにとって合理的と思われる例外がたくさんあります。 初心者にとっては、理解するのはそれほど簡単ではないかもしれません。

image

@weshaggard

System.Reflection.Emitnetstandardパッケージとして公開し続けることは、長期的には良い解決策ではありません。 これにより、標準が再び「false」になり、net / netcoreappでのみ使用できるようになります。 飲み込むのは苦い薬です、私が知っていると信じてください。 System.Reflection.Emitを使用するプロキシライブラリである「LightInject.Interception」とまったく同じ問題があります。 しかし、私はむしろ、このライブラリがどこでも実行できるという消費者に嘘をつくよりもnetcoreappをターゲットにしたいと思います。

@seesharper

IMHO、PlatformNotSupportedExceptionをスローすることは、PCLで見たAPIサブセットのもう1つの現れです。 System.Reflection.Emit.LightWeightの場合と同様に、実際に実装でき、PlatformNotSupportedExceptionをスローする理由はありません。

それらはまったく同等ではありません。 .NET Standardが役立つ唯一の理由は、APIサーフェスが非常に優れているため、単一のビルドを作成して複数のプラットフォームで実行できるためです。 PCLは、API交差サブセットが削減されているため、重要な機能のために複数のプラットフォーム固有のビルドを強制的に作成するため、はるかに有用性が低くなります。 それらの機能は同等ではなく、それらがもたらすソリューションは、ライブラリの作成者と消費者の両方で複雑さが大きく異なります。.NETStandardでは、プラットフォームがサポートしているかどうかを実行時に確認できるため、すべてのプラットフォームで実行される単一のビルドがあります。 Reflection.Emit、そうでない場合は、Lambda Expressions andReflectionにフォールバックします。 これらのAPIが.NETStandardライブラリで利用できない場合、単一のビルドを作成することはできず、移植性のないプラットフォーム固有のビルドの開発と保守に戻る必要があります。

System.Reflection.Emitをnetstandardパッケージとして公開し続けることは、長期的には良い解決策ではありません。 これにより、標準が再び「false」になり、net / netcoreappでのみ使用できるようになります。

プラットフォーム固有のビルドの作成と依存を強制することは、特に、はるかに悪い結果です。 非常に多くの推移的な依存関係がすでにそれに依存しています。 .NET Standardの主な利点は、単一の有用な抽象化を対象とするライブラリとプロジェクトを作成できることです。これを使用して.NETCoreと.NETFrameworkで利用可能な主流の機能にアクセスできない場合、その主な用途を解決できません。 -ケースであり、PCLに勝る利点がなく、.NETエコシステムに抽象化/混乱を追加しているだけなので、存在しない可能性もあります。

PCLはすでに、各プラットフォームで利用可能なAPI機能の共通部分のみを公開する抽象化へのバインドを試みました。これは、各プラットフォームで利用可能なAPIにのみアクセスでき、ひいてはAPIのみを含むため、事実上、戻ってきたいものです。最も制限されたプラットフォームで利用できます。

.NET Standardでより広範なAPIサーフェスを使用すると、はるかに便利になり、ライブラリの作成者は、さまざまなプラットフォームのサポートをどのように処理するかを自由に選択できます。これらのAPIが利用できない場合、そのオプションは存在しません。プラットフォーム固有のビルドを強制し、依存するすべてのライブラリとプロジェクトにプラットフォーム固有のビルドも維持するように強制し、摩擦、断片化を追加し、移植性を減らし、サポートをサポートする.NETStandardをサポートするすべてのプラットフォームに対して作成者がビルドを維持することを選択したプラットフォームのみにサポートを制限しますその機能。

それは好みの問題だけではありません。主流のAPIサポートを削除すると、利用可能なソリューションに破壊的な影響が及ぶ可能性があり、不要なプラットフォーム固有のビルドがライブラリのユーティリティに影響を与え、すべての.NET標準ライブラリとそれらを使用するプロジェクトが破壊されます。

@weshaggard

netstandard2.0でこれらをサポートするための優れたソリューションはまだありませんが、System.Relfection.Emitの所有者( @AtsushiKan @joshfree)は、より長期的なソリューションを見つけようとしています。

プラットフォームを使用しているすべての人にAOTのみを強制するiDiotとコントロールフリークに、悪いプラットフォームルールを形成して修正する必要があることを伝えてはどうでしょうか? (正直に言うと、これが本当の意味であることがわかっています。モバイルの世界で非常に具体的な悪役が数人います。)

@mythzあなたは絶対に正しいです。

@masonwheeler

それが引き起こしたフォールアウトを考えると、refemitパッケージを非表示にすることはイライラすることを完全に理解しています。 また、特に気にしないシナリオに影響を与えるトレードオフが含まれている場合は特に、気にしない実行環境に最適化することは混乱を招く可能性があることも理解しています。

そうは言っても、私はあなたのコメントを建設的ではないので「虐待的」とマークしました。 侮辱的な人々はこれらの問題に対処するつもりはありません。 また、これは私たちが管理するポリシーではないことも考慮してください。 iOSで実行時にコードを生成して実行できないという事実は、Appleによるポリシー決定です。 また、場合によっては、それはポリシーの制限ではなく、技術的な制限です。

リフレクションエミットには3つのオプションがあります。

  1. 現在のパッケージを修正し、.NET Standard2.0上で動作するようにします。 問題は、2.0と比較して.NET Standard 1.xのTypeTypeInfo間の奇妙な継承関係であり、非公開コンストラクターがあります。 詳細を説明することはできますが、ハックに復元せずにパッケージを実際にビルド可能にするためには少し注意が必要です。そのため、当初はパッケージを非表示にすることにしました。

  2. 反射エミットを.NETStandardvNextに追加します。 AOTのみのシナリオをサポートするために、これには、コード生成がサポートされているか効率的か(つまり、解釈ではなく実際の実行を使用するかどうか)を消費者が確認できる機能APIが含まれる可能性があります。

  3. リフレクションエミットを.NETStandardに公開せず、ライブラリの作成者にマルチターゲットを要求します。 これは基本的に、パッケージを非表示にし始めたときの元のパスでした。

現在、最初のオプションに傾いていますが、2番目のオプションもテーブルにあります。

私は2に賛成です。それはそこにあるべきであるほどユビキタスです。 他の理由でとにかく機能チェックが必要です。

私は2に賛成です。それはそこにあるべきであるほどユビキタスです。 他の理由でとにかく機能チェックが必要です。

私もそうですが、現在.NET Standard 2.0に依存している人は、新しいバージョンの標準が必要になるため、役に立ちません。 ただし、問題のAPIはすでに存在します。

そのため、このパッケージをそのまま機能させるための最小限の修正だけでなく、.NET Standard 2.0vNextも修正することを考えています。

@terrajobstオプション1について、オプション2を実行しにくくする何かがありますか? netstandard1.1パッケージグラフを取得する代わりに、 netstandard2.0をターゲットとするパッケージのバージョンを取得することは、短期的な目標としては適切であるように思われます。 次に、標準のvNextの場合、それはその一部になる可能性があり、パッケージはもう必要ありません。

ですから、本当に正当な理由がない限り、私は1と2の両方に投票します。

@bording

ほぼ同時に投稿したようです。 うまくいけば、私のコメントはあなたの質問に対処します:-)

netstandard2.0は、バイナリイメージのバイト配列からアセンブリをロードするSystem.Reflection.Assembly.Load(byte[] rawAssembly)静的メソッドをサポートしていることに注意してください。 これは、純粋なnetstandard2.0下で、すべてではなくほとんどのSystem.Reflection.Emit APIの互換性を実装できることを意味します。

(申し訳ありませんが、PNSEなしでAssembly.Loadをサポートするプラットフォームがいくつあるかわかりません)

@GlassGrass netstandard2.0実装がどのフレームワークに適用されると思いますか?

ILを書き出して、API駆動のILASMのようなアセンブリを生成する実装は確かに想像できますが、それを使用したい現在のフレームワークは見当たりません。

JITを備えた(そしてAssembly.Loadをサポートする)フレームワークは、Ref.Emitを直接サポートし、netstandard2.0バージョンの代わりにRef.Emit実装を提供することもできます。 私はこれが少なくともdesktop / .netcore /.netnativeの場合であることを知っています。 最初の2つはref.emitをサポートして実装を提供しますが、後者はJITを備えておらず、動的なアセンブリの読み込みもサポートしていません。

誰かがcorefxlabで遊んで、Ref.Emit(またはそれ以上)のように見えるSystem.Reflection.Metadata上に何かを書くのは興味深いプロジェクトだと思います。 誰かがすでにそれを見ているかどうかはわかりません。 / cc @nguerrera @tmat

誰かがcorefxlabで遊んで、Ref.Emit(またはそれ以上)のように見えるSystem.Reflection.Metadataの上に何かを書くのは興味深いプロジェクトだと思います。

それは私のプレートにあります:(https://github.com/dotnet/corefx/issues/4491およびhttps://github.com/dotnet/corefx/issues/2800)

https://github.com/dotnet/corefx/issues/2800が最初に表示され

@AtsushiKan :この問題に関する作業がまだ進行中であることを確認できてうれしいです。 これに取り組んでくれてありがとう。

以前に他の場所で次のことを述べました。 System.Reflection.MetadataAssembly.Load(byte[])ができないことの1つは、タイプごとの増分放出です。 あるタイプを発行してから別のタイプを発行することはできません...完全なアセンブリしか発行できません。つまり、動的プロキシタイプの生成に依存するライブラリをモックする場合などにはあまり役に立ちません。

もちろん、単一タイプのアセンブリしか作成できませんでしたが、 [assembly: InternalsVisibleTo]を介して動的に生成されたアセンブリに内部を表示すると、これは潜在的に非効率的で困難になります(ライブラリのモック/テストで必要になることがよくあります)。 これを機能させるには、複数の動的な単一タイプのアセンブリに同じID /厳密な名前を付けることができる必要があります。 (ランタイムは実際にはすでにこれを許可しているかもしれませんが、公式にそれを確認するドキュメントを見つけることができません。)

@stakx IVTを使用する代わりに、動的アセンブリにSystem.Runtime.CompilerServices.IgnoresAccessChecksToAttribute発行して、指定されたアセンブリの非公開メンバーにアクセスできるようにすることができます。

@tmat :これは面白いです。 この属性はどこかに公式に文書化されていますか?

この特別な属性が公式に文書化されていないのは残念です。ランタイムの外でそれを使用するのはちょっとした賭けになります。

これは.NET core 3.0追加されますか?

cc @steveharter @joshfree

@karelz https://github.com/dotnet/corefx/issues/30654は、3.0の作業を追跡し

@joshfreeはこれは

@karelzは、Ref.Emitパッケージがnugetから誤ってリストから除外され、@ weshaggardによってパッケージが再リストされるという問題をカバーしていました。 残りの作業はdotnet / corefx#30654で追跡されるため、この問題は解決できると思います。

OK、それから閉じます:)...残りの作業は上記のようにdotnet / corefx#30654で追跡されます。

このページは役に立ちましたか?
0 / 5 - 0 評価