Tidak ada AppDomains di .NET Core! Mengapa?

88

Apakah ada alasan kuat mengapa Microsoft memilih untuk tidak mendukung AppDomains di .NET Core?

AppDomains sangat berguna saat membangun aplikasi server yang berjalan lama, di mana kita mungkin ingin memperbarui rakitan yang dimuat oleh server dengan cara yang anggun, tanpa mematikan server.

Tanpa AppDomains, bagaimana kita akan mengganti rakitan kita dalam proses server yang berjalan lama?

AppDomains juga memberi kami cara untuk mengisolasi berbagai bagian kode server. Seperti, server websocket khusus dapat memiliki kode soket di appdomain utama, sementara layanan kami berjalan di appdomain sekunder.

Tanpa AppDomains, skenario di atas tidak mungkin dilakukan.

Saya dapat melihat argumen yang mungkin berbicara tentang penggunaan konsep VM dari Cloud untuk menangani perubahan perakitan dan tidak harus mengeluarkan biaya tambahan dari AppDomain. Tapi apakah ini yang dipikirkan atau dikatakan Microsoft? atau mereka memiliki alasan dan alternatif tertentu untuk skenario di atas?

Aditya Pasumarthi
sumber
9
Tetapi .NET Core 5 bukanlah .NET Framework. Ini bukan versi mendatang dari .NET CLR 4.6 tetapi hal lain yang terpisah maka jangan khawatir, AppDomain akan tetap ada.
Adriano Repetti
2
Saya melihat itu, tetapi jika Microsoft mengklaim bahwa .NET Core 5 akan menjadi multi platform (Windows / Linux / Unix), maka saya ingin tahu mengapa mereka ingin menghapus fitur inti seperti AppDomain.
Aditya Pasumarthi
3
Saya kira (tapi itu hanya pendapat saya) mereka lebih sulit untuk diterapkan secara multi-platform, mereka memperlambat banyak hal dan menambah kompleksitas. Tidak banyak orang yang menggunakannya (setidaknya kebanyakan orang tidak melakukannya secara langsung). Jika Anda tidak membutuhkannya, Anda dapat menggunakan .NET Core. Jika Anda membutuhkannya ... jangan gunakan (pikirkan ReFS vs NTFS). Sederhananya .NET Core bukanlah masa depan .NET (sejauh ini) tetapi proyek terpisah. Mungkin meja kerja tetapi yang pasti bukan jalur migrasi atau alternatif 1: 1 (setidaknya sekarang).
Adriano Repetti
@AdrianoRepetti: Pertimbangkan untuk menambahkan ini sebagai jawaban, karena menurut saya ini berguna.
Patrick Hofman
@PatrickHofman itu hanya pendapat saya (komentar kedua), saya dapat menjawab sebagai wiki komunitas tetapi saya menyerahkan tugas ini kepada seseorang yang lebih fasih berbahasa Inggris!
Adriano Repetti

Jawaban:

49

Inti dari himpunan bagian .NETCore adalah untuk menjaga pemasangan .NET tetap kecil . Dan mudah diangkut. Itulah mengapa Anda dapat, katakanlah, menjalankan aplikasi Silverlight pada Windows dan OSX dan tidak menunggu lama saat Anda mengunjungi halaman web. Mengunduh dan menginstal runtime dan kerangka kerja lengkap membutuhkan beberapa detik, memberi atau menerima.

Menjaga agar tetap kecil pasti membutuhkan fitur untuk dipotong. Remoting sangat tinggi dalam daftar itu, itu cukup mahal. Jika tidak, tersembunyi dengan baik, tetapi Anda dapat misalnya melihat bahwa delegasi tidak lagi memiliki metode BeginInvoke () fungsional. Yang juga menempatkan AppDomain pada daftar potong, Anda tidak dapat menjalankan kode dalam domain aplikasi tanpa dukungan jarak jauh. Jadi ini sepenuhnya karena desain.

Hans Passant
sumber
13
IMHO itu tidak ada hubungannya dengan ukuran, tetapi dengan fakta bahwa CoreCLR tidak memiliki penamaan yang kuat, dan karenanya memiliki sistem fusi baru dan cara baru untuk melihat apa itu assembly, identitasnya dan di mana ia dimuat, artinya appdomain sebagai penampung tidak lagi berguna.
Frans Bouma
7
Hmm, tidak. Menjaga ukuran unduhan menjadi 6,6 MB tentu saja memerlukan penghapusan lebih dari satu fitur.
Hans Passant
8
AppDomains dapat berguna secara penuh .NET meskipun Anda tidak menggunakan penamaan yang kuat. (Misalnya, kemampuan AppDomains untuk menyediakan isolasi kesalahan tidak bergantung pada penamaan yang kuat.) Jadi, penghapusan penamaan yang kuat tidak dengan sendirinya menjadi alasan untuk menghapus AppDomains.
Ian Griffiths
5
Saya bingung. Apa hubungan antara .Net Core dan Silverlight?
svick
10
Pemrogram cenderung menganggap bahwa .NETCore baru. Microsoft melakukan sedikit untuk menghilangkan gagasan ini, tidak sedikit pun dengan mengubah nomor versi 5.0 menjadi 1.0. CoreCLR telah ada sejak lama, memulai kehidupan sebagai runtime untuk .NET Compact. Silverlight dan runtime WinRT / UWP adalah penggunaan penting untuk itu sebelum mereka menjadi sumber terbuka. Versi runtime terbaik untuk dipilih, setelah sebelumnya telah di-porting ke OSX dan berbagai prosesor seluler WinCE.
Hans Passant
47

Pembaruan untuk .NET Standard 2 dan .NET Core 2

Di .NET Standard 2 AppDomainkelas ada di sana. Namun, banyak bagian dari API itu akan menampilkan PlatformNotSupportedExceptionuntuk .NET Core.

Alasan utama itu masih di sana adalah untuk hal-hal dasar seperti mendaftarkan handler pengecualian tertangani yang akan berfungsi.

FAQ Standar .NET memiliki penjelasan ini :

Apakah AppDomain bagian dari .NET Standard?

Jenis AppDomain adalah bagian dari .NET Standard. Tidak semua platform akan mendukung pembuatan domain aplikasi baru, misalnya, .NET Core tidak akan mendukung, sehingga metode AppDomain.CreateDomain saat tersedia di .NET Standard mungkin memunculkan PlatformNotSupportedException.

Alasan utama kami mengekspos jenis ini di .NET Standard adalah karena penggunaannya cukup tinggi dan biasanya tidak terkait dengan pembuatan domain aplikasi baru tetapi untuk berinteraksi dengan domain aplikasi saat ini, seperti mendaftarkan penangan pengecualian yang tidak tertangani atau meminta direktori dasar aplikasi .

Selain itu, jawaban teratas dan jawaban lainnya juga dengan baik menjelaskan mengapa sebagian besar AppDomain masih dipotong (misalnya, melempar pengecualian yang tidak didukung).

Jeroen
sumber
21

Domain Aplikasi

Mengapa dihentikan? AppDomain membutuhkan dukungan runtime dan umumnya cukup mahal. Meskipun masih diterapkan oleh CoreCLR, ini tidak tersedia di .NET Native dan kami tidak berencana menambahkan kemampuan ini di sana.

Apa yang harus saya gunakan? AppDomains digunakan untuk tujuan yang berbeda. Untuk isolasi kode, kami merekomendasikan proses dan / atau container. Untuk pemuatan rakitan yang dinamis, kami merekomendasikan kelas AssemblyLoadContext yang baru.

Sumber Dari Blog MSDN

cwishva.dll
sumber
Satu pertanyaan, apa yang Anda maksud dengan For code isolation, we recommend processes and/or containers... Apakah ada api kontainer yang tersedia di .net core?
Ivandro Jao
@IvandroIsmael, artinya "pisahkan aplikasi / modul tunggal Anda menjadi aplikasi / modul / proses / penampung yang berinteraksi terpisah" (kemungkinan besar - ke dalam layanan mikro), yaitu, refactor aplikasi Anda agar tidak menggunakan AppDomains untuk isolasi kode
Burst
10

Pada satu titik, saya mendengar bahwa bongkar muat akan diaktifkan tanpa menggunakan domain. Saya pikir System.Runtime.Loader.AssemblyLoadContextjenis System.Runtime.Loader.dll terkait dengan pekerjaan ini, tetapi saya tidak melihat apa pun di sana yang memungkinkan pembongkaran.

bricelam.dll
sumber
6

Anda tidak membutuhkan AppDomains lagi, Anda sekarang memiliki 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"

dan kemudian Anda bisa mengatakan

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

Bonus jika Anda memasukkannya ke antarmuka IDisposable dari kelas abstrak, maka Anda bisa menggunakan menggunakan, jika Anda mau.

Catatan:
Ini mengasumsikan kelas abstrak tetap dalam rakitan umum

public abstract class MyAbstractClass 
{

     public virtual void foo()
     {}
}

dan kelas yang dihasilkan runtime secara dinamis (menggunakan Roslyn), mereferensikan kelas abstrak dalam perakitan umum, yang mengimplementasikan misalnya:

public class RsEval: MyAbstractClass 
{

     public override void foo()
     {}
}
Stefan Steiger
sumber
5

Saya telah mendengar dalam standup komunitas atau beberapa pembicaraan tentang Microsoft bahwa fitur isolasi AppDomains lebih baik ditangani oleh proses (dan sebenarnya pola umum di platform lain) dan pembongkaran memang direncanakan sebagai fitur normal yang tidak terkait dengan AppDomains.

Thomas
sumber