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?
Jawaban:
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.
sumber
Pembaruan untuk .NET Standard 2 dan .NET Core 2
Di .NET Standard 2
AppDomain
kelas ada di sana. Namun, banyak bagian dari API itu akan menampilkanPlatformNotSupportedException
untuk .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 :
Selain itu, jawaban teratas dan jawaban lainnya juga dengan baik menjelaskan mengapa sebagian besar AppDomain masih dipotong (misalnya, melempar pengecualian yang tidak didukung).
sumber
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
sumber
For code isolation, we recommend processes and/or containers
... Apakah ada api kontainer yang tersedia di .net core?Pada satu titik, saya mendengar bahwa bongkar muat akan diaktifkan tanpa menggunakan domain. Saya pikir
System.Runtime.Loader.AssemblyLoadContext
jenis System.Runtime.Loader.dll terkait dengan pekerjaan ini, tetapi saya tidak melihat apa pun di sana yang memungkinkan pembongkaran.sumber
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() {} }
sumber
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.
sumber