.NET CoreにはAppDomainがありません!どうして?


86

Microsoftが.NETCoreでAppDomainsをサポートしないことを選択した強い理由はありますか?

AppDomainsは、サーバーをシャットダウンせずに、サーバーによってロードされたアセンブリを適切な方法で更新したい場合に、長時間実行されるサーバーアプリを構築するときに特に役立ちます。

AppDomainsがない場合、長時間実行されるサーバープロセスでアセンブリをどのように置き換えるのでしょうか。

AppDomainsは、サーバーコードのさまざまな部分を分離する方法も提供します。同様に、カスタムWebSocketサーバーはプライマリappdomainにソケットコードを持つことができますが、サービスはセカンダリappdomainで実行されます。

AppDomainがないと、上記のシナリオは不可能です。

アセンブリの変更を処理するためにクラウドのVMの概念を使用し、AppDomainのオーバーヘッドを発生させる必要がないことについて話し合う可能性のある議論を見ることができます。しかし、これはマイクロソフトが考えていること、または言っていることですか?または、上記のシナリオに特定の理由と代替案がありますか?


9
ただし、.NET Core5.NETFrameworkではありません。これは.NETCLR 4.6の今後のバージョンではありませんが、別のことを心配する必要はありません。AppDomainはそのままです。
アドリアーノレペッティ2014

2
わかりましたが、Microsoftが.NET Core 5がマルチプラットフォーム(Windows / Linux / Unix)になると主張している場合、AppDomainなどのコア機能を削除したい理由がわかります。
Aditya Pasumarthi 2014

3
マルチプラットフォームで実装するのは難しく、多くのことが遅くなり、複雑さが増すと思います(しかし、それは私の意見です)。それほど多くの人がそれらを使用していません(少なくともほとんどの人は直接それを使用していません)。それらが必要ない場合は、.NETCoreを使用できます。それらが必要な場合は...使用しないでください(ReFSとNTFSを考えてください)。単に.NETCoreは(これまでのところ).NETの未来ではなく、別のプロジェクトです。たぶんワークベンチですが、確かに移行パスや1:1の代替手段ではありません(少なくとも今は)。
アドリアーノレペッティ2014

@AdrianoRepetti:これは便利だと思うので、答えとして追加することを検討してください。
Patrick Hofman 2014

@PatrickHofmanそれは私の意見です(2番目のコメント)、私はコミュニティwikiとして答えることができますが、私はこの義務をより流暢な英語を持つ誰かに任せます!
アドリアーノレペッティ2014

回答:


50

.NETCoreサブセットのポイントは、.NETインストールを小さく保つことでした。移植も簡単です。そのため、たとえば、WindowsとOSXの両方でSilverlightアプリを実行し、Webページにアクセスするときにそれほど長く待つ必要はありません。完全なランタイムとフレームワークのダウンロードとインストールには、数秒かかります。

小さく保つには必然的にフィーチャーをカットする必要があります。リモーティングはそのリストの中で非常に高く、かなり高価です。それ以外の場合は十分に隠されていますが、たとえば、デリゲートに機能的なBeginInvoke()メソッドがなくなっていることがわかります。AppDomainもカットリストに追加されているため、サポートをリモート処理せずにアプリドメインでコードを実行することはできません。したがって、これは完全に仕様によるものです。


12
私見では、サイズとは関係ありませんが、CoreCLRには厳密な名前がないため、新しい融合システムと、アセンブリとは何か、そのID、およびアセンブリがロードされる場所を確認する新しい方法があります。コンテナとしてのappdomainはもはや役に立たないことを意味します。
Frans Bouma 2014

7
うーん、いや。もちろん、ダウンロードサイズを6.6 MBに保つには、複数の機能を削除する必要がありました。
ハンスパッサント2014

7
AppDomainsは、厳密な命名を使用していない場合でも、完全な.NETで役立ちます。(たとえば、障害分離を提供するAppDomainsの機能は、厳密な名前付けに依存しません。)したがって、厳密な名前付けを削除しても、AppDomainsを削除する理由にはなりません。
Ian Griffiths

5
よくわかりません。.Net CoreとSilverlightの関係は何ですか?
svick 2016年

10
プログラマーは、.NETCoreが新しいと思いがちです。Microsoftは、少なくとも5.0のバージョン番号を1.0に変更することによって、この概念を払拭することはほとんどありません。CoreCLRは非常に長い間使用されており、.NETCompactのランタイムとして誕生しました。SilverlightとWinRT / UWPランタイムは、オープンソース化する前の注目すべき用途です。以前にOSXおよびさまざまなWinCEモバイルプロセッサに移植されている、選択するのに最適なランタイムバージョン。
ハンスパッサント2017年

46

.NET Standard2および.NETCore2の更新

.NET Standard 2では、AppDomainクラスそこにあります。ただし、そのAPIの多くの部分は、.NETCore用をスローPlatformNotSupportedExceptionします。

未処理の例外ハンドラの登録などの基本的なもののためにそこにある中で、それはまだだ主な理由になる仕事を。

.NET標準FAQには次の説明があります。

AppDomainは.NETStandardの一部ですか?

AppDomainタイプは、.NET標準の一部です。すべてのプラットフォームが新しいアプリドメインの作成をサポートするわけではありません。たとえば、.NET Coreはサポートしないため、.NETStandardで使用可能なメソッドAppDomain.CreateDomainはPlatformNotSupportedExceptionをスローする可能性があります。

このタイプを.NETStandardで公開する主な理由は、使用率がかなり高く、通常は新しいアプリドメインの作成に関連付けられていないが、未処理の例外ハンドラーの登録やアプリケーションのベースディレクトリの要求など、現在のアプリドメインとのやり取りに関連しているためです。 。

それとは別に、トップの回答やその他の回答も、AppDomainの大部分がまだカットされている理由をうまく説明しています(たとえば、サポートされていない例外をスローします)。


20

アプリのドメイン

なぜ廃止されたのですか?AppDomainはランタイムサポートを必要とし、一般的に非常に高価です。CoreCLRによってまだ実装されていますが、.NET Nativeでは使用できず、この機能をそこに追加する予定はありません。

代わりに何を使用すればよいですか?AppDomainsはさまざまな目的で使用されました。コードを分離するには、プロセスやコンテナをお勧めします。アセンブリの動的ロードには、新しいAssemblyLoadContextクラスをお勧めします。

MSDNブログからのソース


1つの質問、どういう意味For code isolation, we recommend processes and/or containersですか... .netコアで利用可能なコンテナAPIはありますか?
IvandroJao19年

@IvandroIsmaelは、「単一のアプリ/モジュールを個別の相互作用するアプリ/モジュール/プロセス/コンテナーに分割する」(おそらく-マイクロサービスに)、つまり、コードの分離にAppDomainsを使用しないようにアプリをリファクタリングすることを意味します
バースト

10

ある時点で、ドメインを使用せずにアセンブリのアンロードが有効になると聞きました。System.Runtime.Loader.AssemblyLoadContextSystem.Runtime.Loader.dllのタイプはこの作業に関連していると思いますが、アンロードを可能にするものはまだありません。


5

コミュニティのスタンドアップやMicrosoftの講演で、AppDomainの分離機能はプロセス(および実際には他のプラットフォームの一般的なパターン)によってより適切に処理され、アンロードはAppDomainとは関係のない通常の機能として計画されていると聞いています。


5

AppDomainsはもう必要ありません。これで、LoadContextsができました。

public class CollectibleAssemblyLoadContext 
    : AssemblyLoadContext
{
    public CollectibleAssemblyLoadContext() : base(isCollectible: true)
    { }
 
    protected override Assembly Load(AssemblyName assemblyName)
    {
        return null;
    }
}

byte[] result = null; // Assembly Emit-result from roslyn
System.Runtime.Loader.AssemblyLoadContext context = new CollectibleAssemblyLoadContext();
System.IO.Stream ms = new System.IO.MemoryStream(result);
System.Reflection.Assembly assembly = context.LoadFromStream(ms);


System.Type programType = assembly.GetType("RsEval");
MyAbstractClass eval = (MyAbstractClass )System.Activator.CreateInstance(programType);
eval.LoadContext = context;
eval.Stream = ms;
// do something here with the dynamically created class "eval"

そして、あなたは言うことができます

eval.LoadContext.Unload();
eval.Stream.Dispose();

それを抽象クラスのIDisposableインターフェースに入れると、ボーナスとして、必要に応じてusingを使用できます。

注:
これは、共通アセンブリ内の固定抽象クラスを前提としています

public abstract class MyAbstractClass 
{

     public virtual void foo()
     {}
}

動的にランタイムで生成されたクラス(Roslynを使用)は、共通アセンブリ内の抽象クラスを参照します。これは、次の例を実装します。

public class RsEval: MyAbstractClass 
{

     public override void foo()
     {}
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.