Runtime: Jadikan antarmuka sebagai API Penyedia ADO.NET resmi alih-alih kelas

Dibuat pada 26 Sep 2015  ·  174Komentar  ·  Sumber: dotnet/runtime

Dari apa yang saya lihat saat ini di halaman corefx-progress untuk System.Data.Common , antarmuka (IDbCommand, IDbConnection, dll) telah dihapus demi penggunaan kelas abstrak.

Tetapi di API baru, sebagian besar metode utama tidak virtual atau abstrak. Di DbCommand saja kita bisa melihat ini:

public DbConnection Connection { get; set; }
public DbParameterCollection Parameters { get; }
public DbTransaction Transaction { get; set; }
public DbParameter CreateParameter();
public Task<int> ExecuteNonQueryAsync();
public DbDataReader ExecuteReader();
public DbDataReader ExecuteReader(CommandBehavior behavior);
public Task<DbDataReader> ExecuteReaderAsync();
public Task<DbDataReader> ExecuteReaderAsync(CommandBehavior behavior);
public Task<DbDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken);
public Task<DbDataReader> ExecuteReaderAsync(CancellationToken cancellationToken);
public Task<object> ExecuteScalarAsync();

Meskipun metode ini pasti dapat dibuat virtual atau abstrak, akan jauh lebih berguna untuk memiliki antarmuka asli kembali, dan membuat API publik bergantung pada antarmuka ini daripada kelas abstrak.

Ini sangat berguna ketika mengembangkan perpustakaan. Hari ini sangat sulit untuk mengejek pembaca data agar mengembalikan nilai tertentu untuk tujuan pengujian. Hal yang sama untuk memastikan bahwa ExecuteReaderAsync dipanggil, bukan ExecuteReader, dll.

Saya mengusulkan pabrik penyedia sebagai gantinya harus dibuat sebagai antarmuka:

public interface IDbProviderFactory {
    IDbCommand CreateCommand();
    IDbConnection CreateConnection();
    IDbConnectionStringBuilder CreateConnectionStringBuilder();
    IDbParameter CreateParameter();
}

Dan kemudian ikuti dari sana ke penyedia lainnya ke hal-hal seperti IDbDataReader , IDbTransaction , dll.

Kami tahu antarmuka menjadi tidak sinkron karena beberapa alasan di masa lalu dan kelas abstrak dijadikan API resmi, tetapi ini tidak perlu lagi terjadi di corefx.

Perhatikan bahwa ini tidak berarti menghapus System.Data.Common dengan cara apa pun, melainkan membuat kelas Common mengimplementasikan antarmuka ini, dan Anda tidak akan menggunakan System.Data.Common kecuali jika Anda mengimplementasikan penyedia. Aplikasi hanya akan bergantung pada antarmuka saja.

Harap pertimbangkan ini untuk membuat API lebih dapat diuji pada corefx 1.0.

Terkait dengan diskusi tentang dotnet/runtime#14302 dan dotnet/runtime#15269.

area-System.Data

Komentar yang paling membantu

Kami tidak dapat menambahkan anggota ke antarmuka

Benar, dan itu adalah fitur _good_ dari antarmuka. Preferensi untuk kelas dasar abstrak adalah cara teraman untuk membantu entropi API, daripada melawannya.

Meskipun Anda tidak _memiliki_ untuk mengikuti prinsip - Interface Segregation Principle (ISP) menyatakan bahwa _tidak ada klien yang harus dipaksa untuk bergantung pada metode yang tidak digunakannya_.

Jika Anda menambahkan metode baru ke abstraksi yang ada, Anda secara otomatis melanggar ISP.

Anda dapat memutuskan bahwa Anda 'tidak harus mematuhi SOLID' karena Anda adalah Microsoft, dan Anda bekerja dengan BCL, jadi oleh karena itu 'aturan normal tidak berlaku' (bukan kutipan aktual; hanya memparafrasekan yang normal kontra-argumen).

Setelah mempertahankan beberapa proyek sumber terbuka selama 6-7 tahun, menurut pengalaman saya, lebih baik menjaga antarmuka tetap kecil. Jika Anda perlu menambahkan kemampuan baru ke abstraksi, perkenalkan antarmuka baru.

Semua 174 komentar

Mereka akan beralih ke kelas dasar abstrak karena antarmuka tidak dapat diversi.

Saya menduga metode non-virtual memanggil metode lain yang virtual. Metode virtual merusak kinerja sehingga Anda tidak ingin membuat hal-hal virtual tidak perlu.

@JamesNK saya mengerti. Tetapi dengan .NET Core menjadi API baru dan ADO.NET API cukup stabil selama hampir satu dekade, apakah menurut Anda ini masih menjadi perhatian yang valid? Juga, berbicara tentang akses database tebakan saya adalah bahwa biaya metode virtual dikerdilkan oleh biaya akses database.

@NickCraver , @roji , @FransBouma karena kalian tampaknya tertarik dengan ADO.NET API, ada yang ingin dikatakan tentang ini?

@YoungGah , apakah ini sesuatu yang layak dikejar?

Saya menduga metode non-virtual memanggil metode lain yang virtual. Metode virtual merusak kinerja sehingga Anda tidak ingin membuat hal-hal virtual tidak perlu.

Dalam proses mengeksekusi kueri pada basis data jarak jauh dan hasil pemrosesan, nanodetik yang hilang pada panggilan virt dapat diabaikan. Selain itu, ADO.NET menggunakan sistem ini sejak awal (begitu juga banyak API lain di .NET) dan tidak ada yang mengeluh bahwa kode DB mereka sangat lambat karena panggilan metode virtual;)

Saya dapat melihat metode async dalam daftar Anda, jadi saya kira hanya beberapa tahun yang lalu MS tidak dapat menambahkan async ke IDbCommand. Siapa yang tahu apa yang akan terjadi besok yang membutuhkan metode atau properti baru.

Antarmuka tidak versi.

Performa hanyalah salah satu alasan untuk tidak membuat sesuatu menjadi virtual. Mengurangi luas permukaan untuk implantasi mungkin? Saya akan membiarkan seseorang di MS mengatakan mengapa mereka memutuskan untuk tidak melakukannya, saya tidak tahu banyak tentang ADO.NET jadi saya hanya akan berspekulasi.

@JamesNK Saya pikir kekhawatiran Anda valid, tetapi ada 2 poin penting untuk dipertimbangkan:

  1. ADO.NET telah cukup stabil sejak .NET 2.0, yang satu dekade - meskipun API async ditambahkan kemudian, itu tidak mengubah perilaku API, hanya menambahkan rekan-rekan async - Saya tidak melihat ada perubahan besar dalam paradigma driver database dalam waktu dekat
  2. CoreFx seharusnya memiliki ide pembuatan versi yang berbeda, karena Anda dapat menyimpan CLR sebelumnya untuk aplikasi lama. Jadi masalah versi antarmuka seharusnya tidak berdampak seperti itu di sini

Pertimbangkan juga bahwa bahkan server sql di "localhost" akan menghabiskan setidaknya beberapa ms hanya untuk menghubungkan dan mengembalikan kueri kosong. Dalam praktiknya, sebagian besar kueri _fast_ ke database relasional membutuhkan waktu ~20 md.

Mampu mengolok-olok API dengan alat standar seperti NSubstitute atau Moq jauh lebih berharga bagi pengembang saat ini daripada menyimpan mikrodetik dalam pencarian metode virtual.

Saya kira saya tidak memiliki pendapat yang sangat kuat di sini, tetapi berikut adalah beberapa komentar:

  • Setuju dengan hal di atas bahwa menghapus virtual vs non-virtual dapat diabaikan dalam API untuk akses database
  • Kelas dasar memungkinkan ADO.NET untuk menyediakan implementasi, saya rasa itulah yang paling banyak dilakukan oleh metode non-abstrak non-virtual - kelebihan ExecuteReader yang tidak menerima CommandBehavior meneruskan CommandBehavior.Default ke kelebihan itu. Jika Anda beralih ke antarmuka, setiap penyedia harus mengimplementasikan ExecuteReader() dengan boilerplate yang sama persis...
  • Saya tidak yakin ini valid di semua kerangka kerja mengejek utama, tetapi setidaknya di Moq bukankah sama mudahnya untuk mengejek kelas dasar seperti halnya antarmuka?

Jadi secara keseluruhan ide untuk menjatuhkan kelas dasar atau antarmuka tampaknya bagus (lebih sederhana). Karena saya tidak melihat keuntungan apa pun untuk antarmuka (kecuali saya salah tentang kemudahan mengejek), dan kelas dasar dapat menyediakan fungsionalitas umum (yaitu metode non-abstrak non-virtual), saya kira pendekatan Microsoft untuk membuang antarmuka sepertinya baik bagiku...

Saya setuju dengan @roji pada semua poinnya.

@roji hanya sebuah catatan, saya tidak mengusulkan untuk menjatuhkan kelas dasar, saya mengusulkan untuk menambahkan antarmuka sebagai API default. Kelas dasar masih dapat menerapkan perilaku default.

Untuk pengujian, saya mengalami masalah besar saat menguji apakah API saya memanggil metode yang tepat. Untuk memeriksa apakah ExecuteDataReader menerima parameter yang benar misalnya, Anda harus memeriksa metode terproteksi lain yang dipanggil secara internal dengan parameter berbeda. Ini jauh dari ideal.

Saat ini, kecuali saya salah, satu-satunya kerangka kerja yang dapat mengejek API ADO.NET adalah kerangka kerja MS Fakes yang dapat benar-benar mengejek apa pun dengan mencegat panggilan. Moq dan yang lainnya tidak bisa melakukan itu.

Saya tertarik untuk melihat apakah orang lain memiliki masalah serupa.

@roji hanya sebuah catatan, saya tidak mengusulkan untuk menjatuhkan kelas dasar, saya mengusulkan untuk menambahkan antarmuka sebagai API default. Kelas dasar masih dapat menerapkan perilaku default.

Maaf, saya salah paham. Dalam hal ini, bukankah proposisi Anda kurang lebih menjaga hal-hal sebagaimana adanya di .NET (bukan berarti ada yang salah dengan itu)?

Untuk pengujian, saya mengalami masalah besar saat menguji apakah API saya memanggil metode yang tepat. Untuk memeriksa apakah ExecuteDataReader menerima parameter yang benar misalnya, Anda harus memeriksa metode terproteksi lain yang dipanggil secara internal dengan parameter berbeda. Ini jauh dari ideal.

Jika saya memahami skenario Anda (tidak yakin), CallBase Moq berguna untuk skenario semacam ini - implementasi default diwarisi dari kelas dasar

@roji

bukankah proposisi Anda kurang lebih menjaga hal-hal seperti apa adanya di .NET (bukan berarti ada yang salah dengan itu)?

Tidak tepat. Antarmuka API telah ditambahkan di .NET 1.0 dan tidak digunakan lagi pada 2.0. Sejak 2.0, antarmuka ada untuk kompatibilitas, tetapi tidak ada antarmuka untuk ProviderFactory atau kelas lain di Data.Common. Juga tidak ada apa pun untuk async API atau 2.0 atau metode yang lebih baru.

Moq hanya bisa mengejek hal-hal yang bisa diolok-olok. Harus ada beberapa metode yang virtual atau abstrak yang dapat ditimpa, atau metode terproteksi yang dapat dipanggil. API saat ini menyediakan metode untuk beberapa kasus, tetapi tidak untuk sebagian besar kasus. Ada banyak hal yang bersifat internal, pribadi, dan di luar jangkauan kecuali jika Anda menggunakan refleksi. Hanya MS Fakes yang dapat melakukannya karena menggantikan referensi dengan shim, tetapi ini hanya tersedia di VS Enterprise dan tidak berguna untuk proyek open source.

Sepertinya saya memiliki kasus yang sangat spesifik, tetapi tentu saja siapa pun yang pernah mencoba mengejek api ini menghadapi masalah ini. Hanya google, hampir setiap solusi berakhir dengan "mengolok-olok API antarmuka lama atau membuat pembungkus yang dapat Anda tiru":

@nvivo Oke, terima kasih atas detail tambahannya - saya akui saya belum melangkah terlalu jauh dengan mengejek ADO.NET.

Hal yang saya tidak mengerti, adalah mengapa Anda ingin mengejek metode internal, pribadi, dan di luar jangkauan API. Bukankah seharusnya Anda mengejek metode publik yang langsung tersedia untuk kode aplikasi Anda sendiri (yang Anda coba uji)? Saya melihat masalah dengan metode non-virtual (misalnya kelebihan 0-parameter ExecuteReader()), tetapi mengingat bahwa di ADO.NET ini selalu (?) memanggil beberapa kelebihan virtual (misalnya ExecuteReader(CommandBehavior)), apakah ada masalah nyata di sini?

Hanya mencoba memahami skenario masalah Anda, dapatkah Anda memberikan contoh sederhana?

@nvivo Saat ini kami tidak memiliki rencana untuk membawa antarmuka karena masalah versi yang telah ditunjukkan oleh beberapa orang di utas ini. Contoh bagus dari antarmuka yang tertinggal adalah ketika metode async dan streaming ditambahkan di .NET Framework 4.5. Ketika kami menambahkan fitur-fitur baru tersebut, kami dengan hati-hati memeriksa antarmuka yang diperluas. Opsi yang kami miliki saat itu adalah menyediakan InterfaceFooV2 atau antarmuka terpisah untuk asyn dan streaming. Kami tidak ingin menambahkan InterfaceFooV2 karena kami dapat memperkirakan bahwa kami ingin menambahkan lebih banyak API di masa mendatang. Terus menambahkan antarmuka terpisah untuk setiap fungsi baru akan membingungkan karena tidak terikat dengan antarmuka yang ada.

@roji Saya memiliki kasus di mana saya ingin memastikan bahwa kelebihan tertentu dari ExecuteReader dipanggil, dan bukan "salah satu kelebihan". Ini adalah jenis yang Anda miliki hanya di perpustakaan, bukan pada kode pengguna.

@YoungGah terima kasih atas infonya. Saya tutup ini kalau begitu.

Apakah orang yang bertanggung jawab atas perubahan ini tahu efeknya? Antarmuka ADO.NET inti telah ada selama lebih dari satu dekade dan akses data menjadi pusat dari sebagian besar aplikasi bisnis, saya mengalami kesulitan memahami bagaimana tidak dengan sengaja melanggar begitu banyak basis kode yang ada bukanlah prioritas tertinggi? Ini adalah beberapa antarmuka tingkat tinggi yang paling penting di .NET, menghapus jeda ini setiap perpustakaan akses data ADO .NET di luar sana dan akibatnya setiap proyek menggunakannya. Menghapusnya menciptakan fragmentasi buatan, menyebabkan frustrasi dan kebingungan yang akan menghambat adopsi CoreCLR.

Anda masih dapat membuat versi antarmuka dan membuatnya kompatibel dengan sumber hanya dengan menambahkan metode ekstensi untuk semua API Baru yang tidak aktif IDbCommand , misalnya:

public interface IDbCommand
{
    //...
}

public class DbCommand : IDbCommand
{
    void NewApi();
}

public static class DbCommandExtensions
{
    public static void NewApi(this IDbCommand cmd)
    {
        ((DbCommand)cmd).NewApi();
    }
}

Antarmuka inti IDbCommand tidak pernah berubah setelah DNX dirilis dan Anda dapat terus menambahkan fungsionalitas dengan strategi di atas. Anda juga bisa nanti (dalam versi pemecahan utama), menggulung ekstensi ini dan menggabungkannya ke dalam antarmuka inti. Either way kita mendapatkan antarmuka ADO.NET inti stabil yang penting untuk migrasi basis kode yang ada dan akibatnya untuk adopsi CoreCLR.

Saya telah diminta oleh @davkean untuk memberikan contoh nyata tentang dampak penghapusan antarmuka inti ADO .NET. Saya tidak dapat membayangkan perubahan ini dipertimbangkan tanpa mengevaluasi dampak tak terukur yang akan terjadi pada ekosistem .NET yang ada, tetapi sekali lagi itu juga telah dilakukan sehingga ada kemungkinan itu tidak dipertimbangkan - yang akan saya asumsikan di sini- di dalamnya tidak.

Meskipun peran EF sebagai ORM default .NET dan keberhasilannya yang luar biasa dalam menangkap sebagian besar pangsa pasar, masih ada populasi besar pengembang .NET yang lebih memilih untuk menggunakan ORM alternatif karena sejumlah alasan berbeda. Misalnya fitur penting yang berkaitan dengan CoreCLR adalah bahwa mereka memiliki dukungan kelas satu yang berjalan di Mono/Linux/OSX serta mendukung beberapa RDBMS alternatif. Karena CoreCLR sangat cocok untuk pasar pengembang Linux/OSX, semakin banyak dukungan untuk alt RDBM, semakin baik. Sifat penting lainnya dari populasi pengembang yang mengadopsi Micro ORM adalah bahwa mereka telah mengevaluasi di luar default ekosistem MS untuk memilih ORM yang paling sesuai untuk mereka. Dari semua yang saya lihat, ada korelasi tinggi antara pengembang .NET OSS (yaitu anti-Dark Matter) aktif dan pengembang yang mengadopsi Micro ORM, juga saya berharap ini memiliki korelasi tinggi dengan pengadopsi awal CoreCLR - yang proposisi nilai utamanya adalah untuk dikembangkan di OSX/Linux. Ini adalah beberapa alasan mengapa akan bermanfaat untuk menyertakan ekosistem .NET di sekitarnya dalam pengambilan keputusan Anda saat membuat pilihan desain yang melanggar dasar seperti ini.

Unduhan ORM alternatif

Sekilas tentang unduhan NuGet memberikan indikasi seperti apa pangsa pasar non-EF:

NHibernate - 1 jt+
Rapi - 1 jt+
OrmLite - 500rb+
Sederhana.Data - 300k+
PetaPoco - ~
NPoco -

Angka sebenarnya jauh lebih banyak dari ini karena banyak Micro ORM seperti Dapper, Massive, PetaPoco, NPoco, dll dirancang agar sesuai dengan satu drop-in .cs sehingga NuGet tidak melaporkan penggunaan sebenarnya. Ada juga ORM sumber tertutup seperti LLBLGen Pro yang memiliki basis pengguna yang besar tetapi penggunaannya tidak dilaporkan oleh NuGet, demikian juga saya yakin saya telah melewatkan sejumlah ORM lain yang saya lupa/tidak tahu.

Dampak terhadap ORM alternatif

Berkat GitHub, kami dapat melakukan pencarian cepat untuk melihat berapa banyak file sumber berbeda yang berisi inti
IDbConnection , IDbCommand dan IDataReader ADO .NET antarmuka yang terpengaruh oleh perubahan ini:

Koneksi IDbIDbPerintahPembaca Data
hibernasi59181132
Rapi172117
OrmLite1795426
Sederhana.Data29276
NPoco4103

Catatan: hasil ini hanya menampilkan file sumber, jumlah sebenarnya dari referensi yang rusak jauh lebih tinggi.

Dampak terhadap Kode Sumber Pelanggan

Dampak aktual dari perubahan ini juga meluas ke semua dependensi proyek yang menggunakan ORM ini.
Sayangnya efeknya tidak terbatas pada implementasi internal karena juga merusak pelanggan
kode sumber karena banyak Micro ORM hanyalah metode ekstensi melalui Antarmuka ADO.NET sehingga klien
kode terlihat seperti:

IDbConnection db = ...

//Dapper
db.Query<Dog>("select Age = <strong i="49">@Age</strong>, Id = @Id", new { Age = (int?)null, Id = guid });

//OrmLite
db.Select<Author>(q => q.Name.StartsWith("A"));

Salah satu fitur ekstensibilitas dari penggunaan metode ekstensi adalah bahwa ORM ini "terbuka" dan Pelanggan dapat memperluas ORM dengan API kelas satu mereka sendiri dengan menambahkan metode ekstensi dalam proyek mereka sendiri - ini juga rusak.

Jelas setiap kode sumber yang melewati IDbConnection sekarang juga dilarang bekerja di CoreCLR.

Misalnya Antarmuka ADO.NET inti banyak digunakan di seluruh kerangka kerja tingkat tinggi seperti ServiceStack, diadopsi karena ketergantungan minimal untuk mengaktifkan akses data multi-RDBMS. Itu juga diasumsikan dari semua kelas yang tidak mungkin berubah, itu akan menjadi inti ADO.NET Interfaces.

Ringkasan

Saya pribadi heran akan ada masa depan di .NET tanpa antarmuka ini.
Antarmuka dirancang dengan tujuan khusus untuk memungkinkan beberapa implementasi dan ADO.NET adalah satu-satunya
dari "model penyedia terbuka" yang paling penting di .NET. Saya tidak tahu prioritas apa yang menyebabkan antarmuka ini dihapus, tetapi basis kode .NET besar yang ada yang mengandalkan antarmuka ini bersama dengan ekosistem EF .NET alternatif harus diberikan prioritas yang jauh lebih tinggi. Hal ini menyebabkan gangguan yang signifikan dan merupakan penghalang utama yang diperlukan untuk mendukung platform .NET 4.x dan CoreCLR yang ada, memaksa sejumlah kompleksitas tambahan yang tidak sepele yang harus diterapkan ke semua basis kode yang ada yang terpengaruh oleh hal ini.

Persepsi saat ini adalah bahwa ADO.NET/CoreCLR sedang dirancang ulang untuk memberikan dukungan kelas satu untuk EF dan SQL Server dengan mengabaikan ekosistem lainnya - keputusan melanggar non-transparan seperti ini hanya berlaku untuk menegakkan kembali stereotip ini .

Sebagai anggota tim .NET sebelumnya (sekarang saya bekerja di Roslyn), saya sangat terlibat dalam desain asli dari data baru yang umum, bersama dengan tim SQL dan Entity Framework. Saya tidak terlibat di dalamnya saat ini, tetapi saya dapat menambahkan beberapa latar belakang untuk membantu memperbaiki beberapa pernyataan yang saya lihat di twitter dan di atasnya.

Desain System.Data.Common saat ini untuk .NET Core dimulai pada Desember 2012, sekitar 2 tahun sebelum kami open source.

Sasaran:

  • Rancang area permukaan modern untuk .NET Core, yang mengurangi duplikasi konsep ( IDbConnection vs DbConnection ), kebingungan, kesalahan, dan masalah pelapisan (pisahkan SqlClient dari DataCommon, pisahkan DataSet dari abstraksi inti) dari desain asli dari .NET 1.0. Salah satu yang akan dengan mudah diambil, baik oleh konsumen yang sudah ada maupun pengembang _baru_ ke .NET Framework.
  • Aktifkan penyedia dan konsumen untuk membangun satu biner/sumber terhadap .NET Core, lalu jalankan biner yang sama di .NET Framework. Perhatikan, kebalikannya bukanlah tujuan; mampu mengambil .NET Framework biner/sumber dan menjalankannya tanpa beberapa perubahan pada .NET Core.

Koreksi beberapa hal yang beredar:

  • Antarmuka saat ini tidak dapat versi. Kami tidak dapat menambahkan anggota ke antarmuka, dan proposal di atas yang disediakan oleh @mythz melalui metode ekstensi mengharuskan penyedia tetap berasal dari kelas dasar abstrak.
  • System.Data.Common _tidak_ pindah dari model provider. Antarmuka dihapus karena merupakan konsep .NET 1.0 lama yang diganti/diduplikasi oleh kelas dasar abstrak yang diperkenalkan di .NET 2.0. Pada saat kami membuat keputusan ini, setiap penyedia yang kami temukan berasal dari kelas dasar.
  • Seperti antarmuka, kelas dasar dapat diolok-olok.
  • Kami memahami akan ada beberapa perubahan yang diperlukan bagi mereka yang menggunakan antarmuka .NET 1.0, namun, ini adalah port yang sangat sederhana untuk dipindahkan ke kelas dasar. Misalnya, lihat beberapa baris perubahan ini untuk AutoMapper: (https://github.com/AutoMapper/AutoMapper.Data/blob/master/AutoMapper.Data/DataReaderMapper.cs#L14).

Sesuatu yang sulit saya pahami:

Kami tidak dapat menambahkan anggota ke antarmuka

Bagaimana tidak boleh menambahkan anggota ke antarmuka CoreCLR, tidak apa-apa untuk merobeknya sepenuhnya?

proposal di atas disediakan oleh @mythz melalui metode ekstensi mengharuskan penyedia tetap berasal dari kelas dasar abstrak.

Bagian penting adalah bahwa antarmuka ada dan memungkinkan kode sumber yang mereferensikannya untuk dikompilasi.

Jika Anda tidak ingin versi antarmuka, baik EOL mereka, hanya mengembalikan antarmuka seperti sebelum mereka robek dan mengurangi beban sekarang dikenakan pada setiap perpustakaan lain yang menggunakannya. Maksud saya, Antarmuka inti ini tidak pernah usang tanpa peringatan atau jalur migrasi yang disediakan. Namun kita dihukum karena mengadopsi API yang diterbitkan, terkenal, dan stabil sebagai bagian integral ke perpustakaan kita?

itu adalah port yang sangat sederhana untuk dipindahkan ke kelas dasar.

Ini perlu ditambahkan pada setiap file sumber yang mereferensikan Antarmuka ADO.NET, dan memaksa Pelanggan untuk mengotori kode mereka dengan simbol build kustom.

Tampaknya tidak ada perhatian yang sama untuk kompatibilitas mundur di sini, tetapi dengan sengaja menghancurkan pelanggan yang sudah ada di rilis mendatang bukanlah pilihan (saya terkejut itu bahkan dipertimbangkan dengan pangsa pasar ADO .NET yang jauh lebih besar). Kami tidak dapat mematahkan pelanggan 4.x yang ada, namun kami diminta untuk mendukung CoreCLR - Jadi, di mana ini meninggalkan perpustakaan 4.x yang ada yang ingin mempertahankan kompatibilitas mundur yang ada dan juga mendukung CoreCLR? Haruskah kita juga menduplikasi dokumen/contoh?

Bagaimana tidak boleh menambahkan anggota ke antarmuka CoreCLR, tidak apa-apa untuk merobeknya sepenuhnya?

Area permukaan di .NET Core harus kompatibel dengan biner dengan .NET Framework untuk memungkinkan pihak pertama dan ketiga membangun terhadap .NET Core, dan menjalankan portabilitas tanpa perubahan pada .NET Framework. Menambahkan anggota ke antarmuka melanggar itu, karena konsumen anggota tersebut akan gagal ketika mereka menjalankan .NET Framework.

Saya tidak berdebat untuk penghapusan atau penambahan antarmuka ini, saya hanya ingin menambahkan beberapa latar belakang mengapa desain berakhir di tempatnya. Saya akan membiarkan pemilik saat ini termasuk @YoungGah dan @saurabh500 menanganinya.

Hanya untuk meringkas utas, alasan mengapa Anda yakin Microsoft harus mem-porting antarmuka ini, adalah untuk memungkinkan ekosistem dengan mudah melakukan port ke .NET Core, sambil mempertahankan implementasi .NET Framework mereka?

adalah untuk memungkinkan ekosistem untuk dengan mudah port ke .NET Core, sambil mempertahankan implementasi .NET Framework mereka?

Ya.

Hanya untuk meringkas utas, alasan mengapa Anda yakin Microsoft harus mem-porting antarmuka ini, adalah untuk memungkinkan ekosistem dengan mudah melakukan port ke .NET Core, sambil mempertahankan implementasi .NET Framework mereka?

Ya. API eksternal sekarang rusak jika saya mem-port basis kode saya (LLBLGen Pro) ke corefx: Saya kemudian harus mengekspos 2 api atau memecahkan basis kode yang ada untuk semua pengguna saya.

Mungkin tidak apa-apa bagi Anda untuk memecahkan barang-barang kami karena Anda tidak merasakan sakitnya, kami melakukannya. Tidak masalah bagi saya: Saya harus hidup dengan basis kode yang disembelih dan memelihara 2 API yang melakukan hal yang sama, ATAU memecahkan kode pengguna saya karena Anda pikir itu baik-baik saja.

Saya juga tidak mengerti mengapa antarmuka tidak versi, itu hanya antarmuka, seperti kelas memiliki antarmuka juga. CoreFX dapat dengan sempurna menambahkan metode async ke antarmuka.

Area permukaan di .NET Core harus kompatibel dengan biner dengan .NET Framework untuk memungkinkan pihak pertama dan ketiga membangun terhadap .NET Core, dan menjalankan portabilitas tanpa perubahan pada .NET Framework. Menambahkan anggota ke antarmuka melanggar itu, karena konsumen anggota tersebut akan gagal ketika mereka menjalankan .NET Framework.

Solusi mudah: tambahkan antarmuka seperti sekarang. Dan setelah Anda semua sadar bahwa aturan di atas sebenarnya agak bodoh, Anda dapat menambahkan metode yang Anda butuhkan untuk menambahkan antarmuka lama ke antarmuka dan melanjutkan.

Saya bekerja dengan perangkat lunak MS cukup lama sehingga aturan seperti di atas bagus di atas kertas tetapi dalam praktiknya dilanggar, tim MS yang penting membutuhkannya untuk dilanggar. Jika Anda begitu 'terbuka' dan 'berbeda' seperti yang Anda katakan dalam kehebohan pemasaran/pr CoreFX, tunjukkan. Yang saya lihat sehubungan dengan System.Data dan CoreFX adalah 'apa yang dibutuhkan MS dilakukan, apa yang dibutuhkan orang lain ada di backburner atau diabaikan'.

Hal lain yang saya lupa sebutkan: Fowler kemarin menyebutkan di Twitter bahwa Anda membutuhkan semua orang untuk mem-porting barang-barang mereka. Saya harus membayar sendiri untuk mem-porting basis kode 500K LoC saya ke CoreFX, itu membutuhkan waktu, tenaga, dan akan memakan waktu untuk fitur lainnya. Gesekan ekstra yang benar-benar buatan (ini adalah platform baru! Bagaimana bisa ada aturan yang membatasi?) benar-benar tidak membantu sama sekali: itu menambah biaya perawatan ekstra, membutuhkan waktu ekstra untuk mem-port kode dan menguji dan memberikan beban ekstra bagi pengguna kami.

Semua itu di luar jangkauan Anda, dan sepertinya bukan urusan Anda. Tapi Anda lupa satu hal: apa _jika_ kami tidak mem-porting kode kami dan dengan saya lebih banyak orang? Saya bersedia menginvestasikan waktu dan dengan demikian uang saya sendiri untuk mem-porting basis kode besar saya ke kerangka kerja baru Anda yang mengkilap, tetapi maaf untuk mengatakannya, setiap kali saya mengalami masalah, saya bertemu dengan batasan, aturan aneh, dan debat tanpa akhir yang berakhir dengan diam . Iow: Saya merasa sangat ditinggalkan sendirian sementara pada saat yang sama Anda tampak sangat ingin kami menyukai kerangka baru Anda yang mengkilap.

Seperti yang saya katakan sejak lama : Jual saya kerangka kerja ini, CoreFX baru ini. Nah, menjaga gesekan dan memperkenalkan banyak keju yang dipindahkan dan diambil tidak menciptakan insentif besar untuk menginvestasikan banyak waktu (dan uang) ke dalamnya.

Hanya 2 sen saya.

@FransBouma Mari kita coba dan menjaga percakapan ini tetap profesional, produktif, dan fokus pada fakta.

Saya tidak menentang atau menentang penambahan antarmuka. Namun, tidak kompatibel untuk menambahkan metode ke antarmuka. Mari kita berjalan melalui ini:

1) Tambahkan IDbConnection.OpenAsync ke .NET Core
2) Siapa pun yang memanggil metode ini, sekarang akan gagal berjalan di .NET Framework (melanggar prinsip/tujuan inti yang saya sebutkan di atas). Ini juga merusak perancang XAML dan beberapa fitur VS lainnya yang bergantung pada fakta ini.
3) Untuk memperbarui .NET Framework, kami mengirimkan versi baru .NET Framework "4.7" dengan IDbConnection.OpenAsync
4) Setiap jenis yang mengimplementasikan IDbConnection sebelum menambahkan metode ini sekarang gagal dimuat di .NET Framework "4.7"

Inilah sebabnya mengapa kami tidak dapat menambahkan metode ke antarmuka.

Jika saya menyimpan rasa frustrasi saya dengan bagaimana segala sesuatunya berjalan sehubungan dengan masalah komunikasi dengan MS kepada diri saya sendiri, Anda semua tidak akan mengetahuinya dan berpikir semuanya adalah mawar dan pelangi. Jika itu terlihat tidak profesional, biarlah, saya tidak peduli apakah MS menganggap saya seorang profesional atau tidak.

Yang mengatakan: Saya tidak menikah dengan antarmuka, jadi jika mereka pergi, fakta bahwa sejak saat itu ada kelas dan tidak ada antarmuka untuk bekerja secara teori tidak akan membuat saya panda sedih: apa yang harus dilakukan bisa dilakukan secara teori melalui kelas dasar juga, hari ini, karena hari ini semua penyedia ADO.NET utama bermain bagus dan berasal dari kelas dasar (ini belum terjadi di IIRC sebelumnya dengan ODP.NET mengimplementasikan antarmuka tetapi tidak berasal dari kelas dasar). Ini juga alasan mengapa saya awalnya di atas di utas ini tidak benar-benar berpikir menghapusnya adalah masalah besar. Sejak itu saya punya waktu untuk memikirkannya dan saya pikir itu _adalah_ masalah besar.

Kami tidak hidup dalam ruang hampa di Mars, dan middleware/kerangka kerja di bagian bawah tumpukan memiliki masalah sekarang: pengguna versi lengkap .NET saat ini dari kerangka kerja ini ingin tetap menggunakannya di CoreFX karena mereka mengetahui kerangka kerja ini. Memindahkannya ke CoreFX adalah PITA besar, karena berbagai alasan, salah satunya adalah antarmuka yang sering digunakan di API publik yang tidak ada di CoreFX (dan alasan untuk utas ini).

Untuk alasan itu saja saya ingin melihat antarmuka kembali. Bagi saya pribadi bukan karena alasan teknis (misalnya async membutuhkan kelas dasar, sudah berantakan). Saya tahu mereka tidak memiliki metode tertentu, tetapi itu masalah Anda , bukan masalah saya. Menghapusnya menjadikan itu masalah saya dan (memparafrasekan sekarang) respons MS untuk itu adalah: angkat tangan Anda dengan "tidak bisa dilakukan!". Tapi saya tidak memiliki kemewahan itu. Anda menciptakan kekacauan ini, Anda menyelesaikannya. Anda ingin saya mem-porting kode saya, untuk menginvestasikan banyak waktu dan uang (yang harus saya bayar sendiri) untuk mendukung kerangka kerja baru Anda, lalu mengapa Anda membuat masalah _Anda_ masalah _saya_?

Melihat skenario 4 langkah Anda: menambahkan metode ke antarmuka bukanlah masalah JIKA Anda melihat CoreFX sebagai kerangka kerja terpisah. Dan bukankah itu masalahnya? Ini sama dengan Compact Framework bertahun-tahun yang lalu (yang saya lakukan porting framework saya, dan saya belajar beberapa pelajaran sulit yang kemudian memberi tahu saya bahwa porting ke CoreFX tidak akan sederhana, cepat dan mudah dan menjaga dua basis kode tidak akan baik): kita mulai dengan 1 API, lalu seseorang melupakan sesuatu atau beberapa tim dalam MS membutuhkan sesuatu, dan biola perubahan yang melanggar hanya segelintir pengembang tumpukan tingkat rendah yang akan bertemu dan seterusnya dan kedua jalan akan terbelah.

(contoh: Compact Framework lupa 'SerializableAttribute'. Mereka menambahkan bahwa dengan atribut dummy tidak melakukan apa-apa di versi yang lebih baru, tetapi itu memecahkan kode yang mengantisipasi bahwa tidak ada dan yang mendefinisikannya sendiri)

Memisahkan jalan dapat dimengerti: mencoba menjaga hal-hal yang kompatibel terlalu membatasi. Saya memprediksi di sini sekarang bahwa aturan ini akan dilanggar di masa depan.

Melihat hal-hal sebagai 'kompatibel' adalah penting tidak hanya pada level tanda tangan API, tetapi juga pada level _behavior_ API. Mempercayai bahwa keduanya akan sepenuhnya sama (CoreFX dan .NET Full) dalam perilaku API terlalu berisiko: pengembang kerangka kerja harus menguji fungsionalitas yang sama di CoreFX dan di .NET penuh, tidak mungkin pengujian di CoreFX saja cukup untuk menganggap kode bekerja 100% sama di .NET full di masa mendatang: karena bagaimana Anda bisa menjamin itu? Tumpukan panggilan 20 panggilan jauh di CoreFX telah menyentuh begitu banyak kode selain di .NET penuh, detail kecil di sana-sini dan banyak hal berubah.

Inti dari semua ini adalah: ini adalah kerangka kerja yang terpisah: kode yang dikompilasi terhadap CoreFX dapat diharapkan berbeda dari kode yang dikompilasi terhadap .NET full.

Ada beberapa situasi:

1) kerangka kerja memiliki basis kode yang 100% dikompilasi di CoreFX. Ini memberikan dll yang dapat dijalankan di .NET full
2) kerangka kerja memiliki basis kode yang 70% dikompilasi di CoreFX dan 100% di .NET full. Ini memberikan 2 dll: satu untuk CoreFX, dan satu untuk .NET penuh. Ini konyol untuk menjalankan versi CoreFX di .NET penuh, karena salah satu kehilangan 30% dari fungsionalitas.

Dalam kasus 1) Saya mengerti maksud Anda. Dalam kasus 2) (yang merupakan kasus untuk semua kerangka kerja penargetan penuh .NET saat ini, di antaranya _semua_ ORM pihak ketiga) poin Anda benar-benar tidak berarti, karena mereka harus bekerja dengan 2 dll: secara efektif 2 basis kode yang harus dipelihara secara terpisah, diuji secara terpisah dan dimigrasikan ke versi baru mereka sendiri secara terpisah. Apalagi jika CoreFX mendapatkan fitur baru yang belum menjadi bagian dari .NET full (yang akan terjadi). (btw: jika Anda menambahkan DbDataReader.GetSchemaTable() ke CoreFX yang mengembalikan struktur data yang berbeda dari DataTable, karena MS menolak untuk mem-porting itu, kode yang menggunakan DbDataReader.GetSchemaTable di CoreFX akan rusak di .NET full juga. Jika Anda menamakannya berbeda itu akan rusak serta metodenya tidak ada. Iow: kode akan rusak jika hal-hal yang tidak ada dalam _keduanya_ kerangka digunakan. Itu tidak berarti hal-hal sehingga tidak boleh ada di CoreFX).

Tidak memiliki antarmuka di CoreFX membuat situasi kerangka kerja dalam situasi 2) menjadi persisten: mereka tidak dapat bergerak menjadi kerangka kerja yang sesuai dengan 1) karena misalnya API mereka mengekspos antarmuka.

Microsoft menulis ulang barang-barang mereka sendiri sehingga kerangka kerja mereka menjadi kerangka kerja dalam situasi 1) keren, namun kami tidak memiliki anggaran $ juta, 15+ orang di runtime ORM dan mesin PR besar di pihak kami yang akan menghaluskan kerutan melanggar setiap aplikasi di luar sana. Jadi kita terjebak di 2) atau memerlukan sedikit bantuan dari MS untuk pindah ke 1).

Itulah yang dipertaruhkan di sini. Anda mengatakan di twitter "beri tahu kami apa yang Anda butuhkan". Kita telah melakukannya. Berkali-kali. Khusus mengenai System.Data tidak ada komunikasi. Tidak. Tidak ada rencana masa depan, tidak ada diskusi apa yang harus dilakukan, hanya jalan buntu dan kadang-kadang jika orang MS melangkah di dalamnya, orang yang tidak memiliki kepentingan nyata dalam masalah ini. Saya menghargai waktu Anda untuk ini, semakin banyak latar belakang yang kita dapatkan semakin baik, tetapi pada saat yang sama, ini seperti berbicara dengan rekan kerja tentang hal ini: ini tidak akan terpecahkan karena orang yang bertanggung jawab tidak hadir dan tidak berpartisipasi dalam diskusi.

Jika itu membuat saya terdengar frustrasi dan Tuhan melarang 'tidak profesional', maka biarlah.

Terima kasih untuk mendengarkan. Btw saya tidak punya ilusi wrt System.Data: itu akan menjadi kereta api API untuk mem-porting kode ke dan karena tidak ada komunikasi dari orang-orang yang bertanggung jawab dengan pengembang yang menulis kerangka kerja utama di atas API mereka, ada sedikit atau tidak ada harapan. akan berubah. Bukan salahmu, @davkean , ini bukan masalah pribadi.

Saya harus menggemakan frustrasi di atas tentang kurangnya komunikasi. Kami juga membutuhkan sisipan massal dan informasi skema. Tidak ada kemajuan atau komunikasi selama lebih dari sebulan (lihat dotnet/runtime#15269 dan dotnet/runtime#14302) dari fungsionalitas inti yang hilang ini (dalam kedua cara). Namun, Microsoft memberi label kode saat ini sebagai "kandidat untuk rilis", yang dengan sendirinya merupakan pesan "cukup baik." Ini bukan. Hal-hal inti hilang yang perlu ditambahkan dan jika Anda mengikuti utas ini, harus dalam versi pertama untuk alasan versi yang serupa.

Lihat pembaruan terakhir di dotnet/runtime#14302 ("Mengapa DataTable/View/Set Absent?"), dari 22 hari yang lalu menanyakan:

Jadi System.Data.Common adalah fitur lengkap sekarang untuk V1 dari CoreCLR?

Ya, frustrasi bisa dianggap tidak profesional. Nada dan konteks teks menyebalkan dan selalu begitu, tapi itulah yang kami batasi di sini. Saya pikir semua orang mencoba untuk menjadi produktif di sini, tetapi kami mendapatkan sedikit hambatan dari sisi CoreFX pada kemajuan aktual di area System.Data dan itu, terus terang, membuat marah keduanya sebagai penulis perpustakaan dan pengguna bit ini.

Kami membutuhkan bagian fungsional inti ini, antarmuka atau tidak - Saya tidak sulit mengatur antarmuka dan kami telah mem-porting Dapper tanpa mereka. Tetapi kurangnya DataTable, info skema hasil, penyisipan massal, dan semacamnya tidak dapat diterima dalam "kandidat rilis". Microsoft adalah salah satu yang meningkatkan frustrasi dengan pelabelan kode saat ini sebagai RC ketika hampir secara universal disepakati bahwa itu belum siap untuk dirilis. Ya, itu hanya label, tapi itu label yang salah dan yang secara drastis meningkatkan tingkat urgensi karena didasarkan pada jadwal yang sewenang-wenang (yang seharusnya berubah untuk mencerminkan kenyataan). Saya tidak berpikir siapa pun di utas ini bertanggung jawab atas jadwal itu, tetapi perlu disebutkan sebagai faktor utama dalam _level_ frustrasi.

Mari kita kembali ke akar masalah. Kami membutuhkan potongan-potongan ini, dan jutaan pengguna kami membutuhkannya. Jadi mari kita perbaiki.

Jangan lupa NHibernate dengan 1M+ unduhan :

| Koneksi IDb | IDbPerintah | IDataReader |
| --- | --- | --- |
| 59 | 181 | 132 |

Persepsi saat ini adalah bahwa ADO.NET/CoreCLR sedang dirancang ulang untuk memberikan dukungan kelas satu untuk EF dan SQL Server dengan mengabaikan ekosistem lainnya - keputusan melanggar non-transparan seperti ini hanya berlaku untuk menegakkan kembali stereotip ini .

Persepsi itu diperkuat oleh hal-hal seperti ini: https://github.com/dotnet/corefx/issues/4646

Sejauh yang saya tahu, tidak ada cara untuk mengimplementasikan API itu dengan cara apa pun yang berguna di luar perakitan SqlClient.

Saat ini saya baik-baik saja dengan pengujian tanpa antarmuka. Tapi sejujurnya saya tidak mendapatkan alasan dengan versi antarmuka dan kompatibilitas.

Bukankah ide dari .NET Core adalah bahwa itu adalah kerangka kerja baru tanpa beban kompatibilitas, dan itu dibundel dengan aplikasi Anda, jadi Anda tidak harus berurusan dengan masalah seperti itu? Penyedia sudah tidak kompatibel dengan yang ada di .NET karena kurangnya hal-hal seperti skema dan tabel data, jadi apa yang akan merusak kompatibilitas? Jika antarmuka berubah, kompilasi saja dengan versi baru dan bundel dengan aplikasi Anda.

Kedengarannya seperti sebagian besar alasan untuk desain hanyalah kekhawatiran dari kerangka lama yang tidak berlaku untuk yang baru. Bagaimanapun, mari kita lihat bagaimana hasilnya dalam praktik.

Bagi pengguna yang berniat mendukung banyak kerangka kerja, dan secara historis menargetkan antarmuka... Saya hanya ingin berbagi tumpukan jelek yang digunakan Dapper; Saya tidak mengatakan ini _baik_, tetapi cukup untuk membuatnya dikompilasi. Tentu saja, ini digandakan dalam tumpukan besar file... Saya terutama membagikan ini untuk menekankan dampak lain:

https://github.com/StackExchange/dapper-dot-net/blob/master/Dapper/SqlMapper.cs#L6 -L16

Kami tidak dapat menambahkan anggota ke antarmuka

Benar, dan itu adalah fitur _good_ dari antarmuka. Preferensi untuk kelas dasar abstrak adalah cara teraman untuk membantu entropi API, daripada melawannya.

Meskipun Anda tidak _memiliki_ untuk mengikuti prinsip - Interface Segregation Principle (ISP) menyatakan bahwa _tidak ada klien yang harus dipaksa untuk bergantung pada metode yang tidak digunakannya_.

Jika Anda menambahkan metode baru ke abstraksi yang ada, Anda secara otomatis melanggar ISP.

Anda dapat memutuskan bahwa Anda 'tidak harus mematuhi SOLID' karena Anda adalah Microsoft, dan Anda bekerja dengan BCL, jadi oleh karena itu 'aturan normal tidak berlaku' (bukan kutipan aktual; hanya memparafrasekan yang normal kontra-argumen).

Setelah mempertahankan beberapa proyek sumber terbuka selama 6-7 tahun, menurut pengalaman saya, lebih baik menjaga antarmuka tetap kecil. Jika Anda perlu menambahkan kemampuan baru ke abstraksi, perkenalkan antarmuka baru.

Jika ada upvotes di sini, saya akan upvote komentar

Komentar bijak dari

@FransBouma , kami akan menambahkan fungsionalitas pengganti DbDataReader.GetSchemaTable() dengan cara yang tidak akan merusak kerangka kerja penuh.
@NickCraver , SqlBulkCopy ada dalam rencana masa depan kami dan kami sedang mengerjakan skema. Kami lambat dalam membuat kemajuan pada skema karena kami juga perlu membuat kemajuan yang wajar dalam membuat tumpukan kami bekerja di platform-x.
@mythz , terima kasih telah memberikan contoh, angka, dan penilaian tentang dampak pelanggan. Kami akan meninjau mereka.

@YoungGah Harap perbarui masalah yang terkait dengan informasi sehingga masalah ini tetap terbarui, misalnya https://github.com/dotnet/corefx/issues/1039 , karena jika tidak, info yang jarang tersebar di mana-mana. Sangat menyenangkan Anda akan menambahkan GetSchemaTable (dan yang setara dengan DbConnection, jangan lupa yang itu!), tetapi sangat sulit untuk mendapatkan info tentang apa yang akan terjadi dan _kapan_. Apakah ada rencana apa yang akan ditambahkan kapan? Yang harus kita lakukan sekarang adalah petunjuk bahwa di 'masa depan' mungkin ada sesuatu yang ditambahkan. Itu tidak terlalu bagus untuk merencanakan port basis kode, jujur.

@FransBouma , ya, saya akan memperbarui utas lainnya juga. Adapun permintaan Anda tentang informasi lebih lanjut tentang apa dan kapan akan tersedia, saya sepenuhnya mengerti mengapa Anda membutuhkannya. Saya akan menerbitkan daftar yang akan menunjukkan apakah fitur/fungsi akan tersedia di v1, dihapus dengan sengaja, akan tersedia setelah v1, atau desain ketersediaan di masa mendatang tertunda. Saya akan mencoba mempostingnya selama 2 minggu ke depan. Adapun fungsi get schema pada fungsi DbDataReader dan DbConnection, rencana kami adalah untuk membuatnya tersedia untuk rilis rc2. Jika rencana berubah karena alasan yang tidak terduga, kami akan memperbarui komunitas.

Apa yang pernah terjadi di sini, dan untuk referensi di masa mendatang @YoungGah; IDataReader memiliki ketergantungan pada DataTable, yang memiliki ketergantungan pada DataSet (yang kami anggap sebagai lapisan terpisah - karena kebijakannya berat, tidak seperti jenis ini yang bebas kebijakan), jadi ada beberapa pekerjaan desain di sini untuk memecahkannya jika antarmuka ini pernah ada membawa kembali.

Saya akan memberikan suara lain di sini untuk pendekatan @ploeh ; memiliki antarmuka, tetapi jauh lebih halus daripada sebagian besar antarmuka saat ini di BCL. Ini berkaitan dengan komentar @davkean tentang decoupling serta menangani versi.

Mengapa Anda tidak memiliki antarmuka baru yang mewarisi yang lama. Usang yang lama. Hapus yang lama di masa depan. Setidaknya kemudian Anda dapat memperluasnya dan tidak merusak penggunaan yang ada.

Atau beberapa antarmuka yang lebih kecil. Saya baru saja sampai ploehs komentar.

Saya tidak mengerti kebutuhan ini untuk memiliki kompatibilitas yang sempurna dengan .NET asli. Tidak ada yang perlu dilanggar di sini, ini adalah kerangka kerja baru dan kesempatan sempurna untuk memutuskan hubungan dengan kode lama dan menerapkan perubahan yang diperlukan untuk waktu yang lama tetapi akan merugikan dalam kerangka asli.

Ketika saya mengusulkan antarmuka kembali, saya tidak berpikir untuk membawa antarmuka 1.1 asli, tetapi memperbarui antarmuka dengan desain baru. Mungkin ada lebih banyak lagi, seperti yang dikatakan @ploeh .

Antarmuka ya, dukungan warisan jika memungkinkan, tetapi seharusnya tidak menjadi prioritas saat ini.

Dibuka kembali karena ada banyak minat dalam topik ini.

Tidak ada yang perlu dilanggar di sini, ini adalah kerangka kerja baru dan kesempatan sempurna untuk memutuskan hubungan dengan kode lama dan menerapkan perubahan yang diperlukan untuk waktu yang lama tetapi akan merugikan dalam kerangka asli.

Jadi peluang sempurna untuk menyingkirkan antarmuka asli yang dirancang dengan buruk dan menstandarisasi kelas dasar seperti yang sudah dilakukan ADO.NET? :muka mengejek:

Serius, Anda memiliki pilihan antara API bersih atau kompatibilitas mundur. Pilih salah satu. Saya tidak melihat cara untuk memiliki kue Anda dan memakannya juga.

@JamesNK tapi itulah intinya. Kompatibilitas mundur tidak diperlukan, titik.

Anda bercanda, tetapi API desain buruk dengan antarmuka buruk karena dirancang dengan buruk, bukan karena antarmuka. =) Ini tidak seperti antarmuka yang tidak digunakan sama sekali di NET atau ini adalah sesuatu yang baru. Cukup rancang benda itu dengan benar kali ini dan lanjutkan.

ADO.NET adalah salah satu bagian kode yang paling stabil di semua .NET. Itu memiliki dua atau tiga perubahan serius dalam 15 tahun. Ini adalah API yang sempurna untuk menstabilkan antarmuka dan membuatnya lebih sederhana untuk semua orang.

Sebagai catatan, topik ini di sini adalah salah satu masalah yang paling banyak dikomentari juga, dan memiliki diskusi panjang yang sama tentang antarmuka vs metode virtual, testabilitas, dan lainnya.

@nvivo harus saya akui, saya bingung. Setelah kami menetapkan bahwa kelas dasar memungkinkan pengujian, utas ini berubah menjadi membawa kembali antarmuka untuk mengaktifkan porting kode .NET Framework ke .NET Core. Bagaimana mendesain ulang antarmuka dan memperkenalkan sesuatu yang baru membantu itu?

Mengapa kami tidak dapat memiliki antarmuka asli untuk kompatibilitas mundur dan melanjutkan dengan apa pun yang Anda pilih (baik kelas abstrak atau antarmuka kecil)? Antarmuka asli bisa duduk di atas tumpukan baru dan memberikan kompatibilitas ke belakang. Bagian ini juga bisa opsional.
Itu akan membuat porting mudah dan masih memungkinkan cara baru.

@davkean

Saya tidak bisa menanggapi semua orang yang berkomentar di sini. Saya mengusulkan menggunakan antarmuka sebagai API ADO.NET, diperbarui ke API baru saat ini. Saya tidak meminta untuk membawa antarmuka asli dan semua masalah yang dimilikinya. Tujuannya adalah untuk memiliki API yang didefinisikan lebih bersih dan membuatnya lebih mudah untuk mengejeknya dan menguji kode yang bergantung padanya, sebagian besar perpustakaan abstraksi data dan bukan kode pengguna.

Antarmuka lebih baik dalam menggambarkan API seperti yang dikatakan @ploeh dengan bijak, dan jauh lebih mudah untuk diejek. Desain saat ini sangat buruk dalam hal mengejek, dan mengharuskan Anda untuk mengimplementasikan hampir seluruh penyedia sebagai perpustakaan untuk melakukan tes sederhana. Jika itu tidak penting bagi semua orang, saya bisa mengerti. Tapi saya pasti tidak setuju itu cukup dapat diuji hari ini. Menguji apakah suatu metode A dipanggil dengan parameter X dengan memeriksa apakah metode B disebut C dengan parameter X, Y, Z tidak ideal.

Sekarang, hanya untuk melihat bagaimana kelas sudah membuat desain yang buruk:

  • Mengapa DbCommand memiliki properti DesignTimeVisible ? Apakah waktu desain mendukung persyaratan koneksi untuk didefinisikan sebagai koneksi?
  • Mengapa ada acara untuk memberi tahu perubahan status tetapi tidak memberi tahu hal-hal lain seperti perintah yang dijalankan atau transaksi dimulai? Apakah notifikasi bahkan merupakan persyaratan untuk koneksi yang ada atau sesuatu yang membuatnya lebih mudah untuk membangun UI?
  • Apakah ConnectionStringBuilder merupakan persyaratan bagi penyedia untuk ada? Atau lebih dari hal yang menyenangkan untuk membuat penyihir VS bekerja di luar kotak?
  • Mengapa DbDataReader mendefinisikan metode Get untuk beberapa tipe inti tetapi tidak menambahkan untuk yang lain seperti GetByteArray() dan GetDateTimeOffset() ? Dan apakah mengambil TextReader bahkan diperlukan jika ini dapat dilakukan di luar menggunakan string atau stream? Jika ini adalah antarmuka, apakah metode seperti ini akan ditambahkan ke API atau dibuat sebagai metode ekstensi atau pembantu di kelas konkret (seperti keluarga GetSql* di SqlDataReader)?

Ini semua adalah pertanyaan retoris. Saya yakin semuanya memiliki jawaban yang meyakinkan dan hal-hal telah dipertimbangkan. Intinya adalah bahwa desain saat ini jelas bukan sesuatu yang dianggap sebagai definisi API , sesuatu yang mungkin akan lebih diperhatikan dengan antarmuka.

Sejujurnya, dari luar diskusi tentang desain terdengar seperti ini:

  • mari kita simpan acara ini di sini karena lebih mudah bagi penyihir di studio visual untuk bekerja di luar kotak
  • mari kita hapus metode pengambilan skema karena kita memiliki EF dan itulah yang harus digunakan semua orang di dunia, titik.
  • mari kita pertahankan metode kenyamanan ini karena didukung sejak .NET 1.1 dan kami tidak akan pernah merusak kompatibilitasnya!
  • mari kita hapus datatables dan datasets dan buat semua orang yang berasal dari .NET 1.1 mengubah seluruh basis kode mereka!
  • mari kita bangun model penyedia baru yang berfokus pada komputasi awan, komunitas, sumber terbuka, dan aplikasi masa depan...
  • ... dan mari kita buat model ini berdasarkan kebutuhan kemarin menggunakan SqlClient sebagai _sole_ test case!
  • mari kita buat kerangka kerja baru yang akan dibundel dengan setiap aplikasi, jadi tidak ada yang perlu khawatir tentang pembaruan yang merusak aplikasi mereka _sekali lagi_!
  • .. kemudian mari kita membuat keputusan untuk tidak menambahkan antarmuka karena perubahan apa pun dapat merusak pembaruannya!

Ya, ada sedikit kata-kata kasar di sana dan diskusi ini tidak ke mana-mana =)... Tapi hanya ingin mengeluarkan ini dari dadaku. Ini tahun 2015, semuanya rusak sepanjang waktu dan kami sudah terbiasa. Akan ada 20 pembaruan untuk ASP.NET MVC di tahun-tahun mendatang yang akan menyebabkan lebih banyak perubahan yang melanggar daripada perubahan antarmuka di ADO.NET.

Saya masih menyukai .NET dan apa yang Anda lakukan dengannya secara umum, saya yakin itu terburu-buru untuk mengeluarkan .NET Core v1 tepat waktu dan tidak semuanya akan sempurna. Saya hanya berharap komunitas dapat membantu mengarahkan ini ke arah lain seiring berjalannya waktu dan Anda tidak takut untuk merusak barang-barang saat kami bergerak.

Untuk pengelola ORM, mengapa tidak?

``` c#

jika COREFX

namespace System.Data {
antarmuka publik IDbConnection { ... }
}
```

dan gunakan pola adaptor untuk membungkus System.Data baru dengan implementasi Anda sendiri? Bahkan Anda bisa membuat paket kode sumber terbuka untuk itu dan berbagi.

It's 2015, everything breaks all the time and we're used to it. There will be 20 updates to ASP.NET MVC in the next years that will cause a lot more breaking changes than interface changes in ADO.NET.

I still love .NET and what you're doing with it in general, I'm sure it's a rush to get .NET Core v1 out in time and not everything will be perfect. I just hope the community can help steer this to other directions as the time goes and you're not afraid to break things as we move.
- nvivo

Ini masalahnya; alih-alih pendekatan yang dipertimbangkan, kami mendapatkan penulisan ulang yang terburu-buru untuk memenuhi beberapa tenggat waktu yang sewenang-wenang.
Saya akan lebih cepat terlambat, Q4/16 jika perlu, daripada memiliki beberapa barang rusak baru yang mengkilap. Ini tahun 2015 dan semuanya rusak adalah pembenaran yang mengerikan.

@thefringeninja yang menambahkan ketergantungan yang sama sekali tidak perlu dan membingungkan yang hanya berfungsi dengan setengah sistem (dalam kasus bersama), atau mengarah ke tabrakan nama yang membutuhkan extern alias untuk dihapus (dan banyak kebingungan mengapa metode yang digunakan a System.Data.IDbConnection tidak akan menerima System.Data.IDbConnection yang berbeda tetapi sama yang Anda tawarkan). Pada dasarnya, itu akan membuat segalanya 10 kali lebih buruk.

Bisakah Anda memberikan contoh konkret @mgravell ? Saya dapat melihat bagaimana ini akan rusak jika Anda menggunakan Type.GetType("System.Data.IDbConnection, System.Data") , atau mungkin dalam skenario PCL.

Jika orm A mendefinisikan System.Data.IDbConnection, dan orm B mendefinisikan
System.Data.IDbConnection, maka sekarang ada dua yang sama sekali berbeda dan
antarmuka yang tidak kompatibel yang memiliki nama/namespace yang sama, konflik, dan
tidak benar-benar berfungsi dari penyedia DB mana pun. Itu tidak menyelesaikan apa pun,
pada dasarnya. Lebih buruk: itu menyewakan ke API yang tidak dapat digunakan di mana seseorang berharap untuk lulus
di SqlConnection atau NgpSqlConnection - dan itu tidak berfungsi.

Bahkan Anda bisa membuat paket kode sumber terbuka untuk itu dan berbagi.

Jika bukan System.Data.Common, maka itu berarti DbConnection tidak mengimplementasikannya, dan : Anda sebaiknya tidak repot.

Anda tidak akan pernah mendapatkan konsensus untuk setiap pengelola penyedia ORM atau ADO .NET untuk mengambil ketergantungan pihak ketiga eksternal (cukup banyak jaminan SQL Server tidak akan) dan 2 perpustakaan mendefinisikan ulang antarmuka inti BCL tidak dapat digunakan bersama. Lebih buruk lagi untuk kerangka kerja tingkat tinggi (seperti ServiceStack) yang mereferensikan antarmuka System.Data di lib inti (yang sekarang perlu ditentukan) tidak akan lagi dapat menggunakan ORM apa pun yang tidak mereferensikan antarmuka yang sama - yang tidak -satu akan atau harus.

Satu-satunya cara Anda dapat memastikan setiap pustaka mereferensikan antarmuka System.Data yang sama adalah jika mereka dipulihkan dengan kelas dasar yang mengimplementasikannya - yang saya masih belum jelas tentang apa kerugiannya.

@mgravell ah ketergantungan transitif, belum mempertimbangkan itu. :+1:

Anda tahu saya tidak mengerti mengapa ini menjadi masalah kecuali Anda menggabungkan kode Anda dengan erat ke kode yang tidak Anda miliki. Lindungi kode Anda dari ketergantungannya! Bungkus dan abstrakkan. Ada banyak cara untuk melakukan ini dan membuat kode Anda dapat diuji. Banyak yang disebutkan di atas. Integrasi Anda menguji bit yang tidak Anda miliki. Itulah cara kerjanya. Anda tidak boleh mengejek objek BCL! Jika ya, maka desain Anda tidak bagus.

@nvivo Saya mengerti bahwa ini adalah masalah asli Anda, tetapi arahnya sekarang telah berubah menjadi utas tentang mengembalikan antarmuka era v1 karena alasan yang sesuai. Mari kita tetap fokus pada itu - jika Anda ingin mendiskusikan membuat perubahan pada area permukaan saat ini, silakan ajukan masalah baru.

@mythz Ada dua masalah yang kami miliki dengan antarmuka; 1) mereka membawa ketergantungan (berat) pada DataSet, yang tidak termasuk dalam abstraksi bebas kebijakan dan 2) mereka membawa serangkaian abstraksi paralel ke kelas dasar tetapi dikunci dengan area permukaan v1. Kami ingin menghindari kebingungan itu.

Saya setuju bahwa pihak ke-3 tidak dapat menyediakan antarmuka ini - antarmuka ini perlu diimplementasikan pada abstraksi inti agar bermanfaat.

Saya mengerti bahwa ini adalah masalah asli Anda, tetapi arahnya sekarang telah berubah menjadi utas tentang mengembalikan antarmuka era v1 karena alasan yang sesuai. Mari kita tetap fokus pada itu - jika Anda ingin mendiskusikan membuat perubahan pada area permukaan saat ini, silakan ajukan masalah baru.

Ini sama sekali tidak masuk akal.

@nvivo artinya, Anda bukan orang yang bermasalah meskipun telah mengajukannya - terbukti dengan menutupnya. Masalahnya adalah tentang memulihkan antarmuka System.Data untuk meringankan beban mendukung seluruh ekosistem yang bergantung padanya. Anda tampaknya baik-baik saja dengan:

Ini tahun 2015, semuanya rusak sepanjang waktu dan kami sudah terbiasa.

Tapi ini bukan strategi yang memuaskan bagi kita yang harus mendukung basis kode yang ada dan basis kode Pelanggan kami, dan jelas tidak boleh menjadi strategi default untuk penjaga perpustakaan BCL yang mempengaruhi semua .NET.

Tapi ini bukan strategi yang memuaskan bagi kita yang harus mendukung basis kode yang ada

@mythz Ini di luar konteks. Itu bukanlah apa yang saya maksud. Semua orang di sini harus mendukung basis kode yang ada, saya ragu ada pendatang baru di .NET dalam diskusi.

Masalah dengan apa percakapan ini berubah adalah bahwa itu tidak masuk akal. .NET Core adalah kerangka kerja baru, bukan peningkatan. Banyak .NET API lengkap yang ada tidak ada dan tidak akan ada. Kompatibilitas mundur tidak akan berfungsi seperti itu.

@nvivo Sentimen yang tepat inilah mengapa masalah ini tidak berlaku untuk Anda. Jika menurut Anda kompatibilitas mundur tidak penting, Anda belum pernah mencoba mendukung basis kode yang bermakna yang menargetkan banyak platform - Anda juga tidak berbicara atas nama tim CoreCLR. Pustaka ini tidak dikembangkan dari awal, jika Anda membaca di atas, Anda akan menemukan bahwa tujuan utama pustaka CoreCLR untuk berjalan pada .NET Framework penuh. CoreCLR adalah target platform lain yang mem-porting library yang ada sangat penting untuk keberhasilannya, sesuatu yang secara aktif didorong oleh tim .NET dan yang saat ini terhalang oleh antarmuka yang hilang ini.

Dengan semua pembicaraan tentang antarmuka yang tidak ramah versi ini membuat saya berpikir tentang bagaimana bahasa pemrograman Go menghindari masalah ini dengan antarmuka implisit.

Saya diminta untuk memperluas apa yang saya maksud dengan abstraksi _bebas-kebijakan_.

Pada dasarnya, dengan bebas kebijakan yang saya maksud adalah abstraksi System.Data.Common berisi hampir nol aturan bisnis - yang mereka lakukan hanyalah menyediakan bentuk API yang harus diterapkan oleh penyedia tertentu. Ini berbeda dengan DataSet, yang memiliki banyak aturan dan kode bisnis. Jenis bebas kebijakan, karena konstruksinya, cenderung lebih jarang membuat versi daripada jenis yang berisi kebijakan, karena lebih sedikit kode, sehingga lebih sedikit bug dan perubahan desain. Kami ingin abstraksi dan tipe yang _dipertukarkan_[1] antara pustaka pihak ketiga ke versi yang jarang[2] untuk mengurangi jumlah masalah yang Anda temui saat mengoordinasikan dependensi di seluruh grafik paket besar. Anda tidak dapat menyematkan atau menggabungkan jenis pertukaran sebagai bagian dari aplikasi Anda, sedangkan jenis non-pertukaran Anda dapat melakukannya. Oleh karena itu, mengapa kami ingin mereka berpisah.

[1] Dengan _exchanged_, maksud saya tipe yang cenderung muncul di API publik. Misalnya, kami menganggap Collection<T> sebagai tipe pertukaran, tetapi bukan List<T> .
[2] Menggunakan versi semantik untuk ini akan menyebabkan jeda yang hampir identik dengan di atas dengan antarmuka yang dihapus, karena Anda "membagi" ekosistem; perpustakaan perlu membuat keputusan apakah akan menargetkan perpustakaan sebelum atau sesudah jeda, atau bercabang sendiri untuk menangani pemisahan.

@mythz Saya harus mendukung orms/pelanggan sebagai bagian dari aplikasi komersial dan kode yang ada.... Saya tidak mengatakan saya setuju dengan kedua sisi tetapi faktanya adalah bahwa dnx adalah kerangka kerja/runtime yang benar-benar baru. Jika tidak memiliki beberapa antarmuka, tangani itu ... dengan arahan kompiler.

Jika tidak memiliki beberapa antarmuka, tangani itu ... dengan arahan kompiler.

Oh? bagaimana dengan metode yang mengembalikan IDataReader, atau metode yang menerima IDbConnection? Atau IDbTransaksi? Bagaimana Anda akan #ifdev mengatasinya, jika kode _customers_ Anda menggunakan api itu?

'Atasi itu'... kesombongan macam apa itu?

Sederhana, perbarui paket yang mendasarinya (organisasi Anda) untuk mengembalikan tipe Anda sendiri atau tipe dasar yang telah mereka dukung sejak 2.0. Jika Anda menargetkan versi .net yang lebih lama, Anda dapat menggunakan arahan untuk mengembalikan antarmuka dan menandainya sebagai usang.

Ya itu memang menyebalkan, tapi saya yakin mereka (individu yang sangat cerdas yang selalu memikirkan hal ini) melakukannya untuk alasan yang bagus saat itu (kembali ke .net 2.0). Bisakah pembicaraan terjadi dan mungkin ini akan berubah tentu saja .. Tetapi faktanya adalah orang-orang yang meningkatkan ke runtime baru harus melakukan beberapa pekerjaan. Ini bukan klik tombol di ui mewah dan ada pekerjaan yang cocok untuk mereka .. Tetapi pada saat yang sama, saya setuju dengan Anda bahwa memutakhirkan ke kerangka kerja baru harus lebih mudah daripada pergi dan mengganti banyak jenis.

@FransBouma dia mungkin seseorang yang menganjurkan penamaan yang kuat juga.

@FransBouma @phillip-haydon dapat membawa trolling Anda ke tempat lain, Anda tidak dapat berharap untuk bertindak seperti itu dan orang-orang menganggap Anda serius. Lihatlah kontribusi / proyek open source saya yang terlibat jika Anda memiliki keraguan ... Saya harus menghadapi ini ... bagaimanapun ...

Sebagai catatan, saya menentang penamaan yang kuat.

menghadapinya...

Dan kamu bilang aku trolling?

" @FransBouma dia mungkin seseorang yang menganjurkan penamaan yang kuat juga." di luar topik, dan tidak terlalu membantu pembicaraan ini. Ya rasanya seperti trolling Anda ..

Satu fakta penting untuk dipertimbangkan dalam diskusi ini adalah bahwa antarmuka IDb* tidak digunakan lagi sebagai API untuk ADO.NET di .NET 2.0 satu dekade lalu ketika kelas dasar diperkenalkan. Mereka tidak ditandai sebagai usang, tetapi apa pun yang dibangun sejak saat itu bergantung pada kelas dasar. Penyedia App.config dan dukungan string koneksi muncul dalam pikiran.

Jika Anda memiliki kode yang bergantung pada antarmuka tersebut, Anda membuat kode terhadap API yang sangat usang tanpa dukungan untuk hal-hal seperti metode async, yang berarti Anda tetap harus memperbaruinya jika Anda ingin orang tetap menggunakannya.

Sederhana, perbarui paket yang mendasarinya (organisasi Anda) untuk mengembalikan tipe Anda sendiri atau tipe dasar yang telah mereka dukung sejak 2.0. Jika Anda menargetkan versi .net yang lebih lama, Anda dapat menggunakan arahan untuk mengembalikan antarmuka dan menandainya sebagai usang.

Ini adalah API publik, digunakan oleh ribuan aplikasi dan API tersebut telah digunakan untuk publik dan digunakan sejak .net 1.0. Ini tidak 'sederhana', sebaliknya. Kita tidak bisa begitu saja mengubah API karena Microsoft berpikir itulah yang harus mereka lakukan untuk membuat hidup kita lebih baik: itu akan menjadi beban besar bagi pengguna kita dan juga bagi kita.

Ya itu memang menyebalkan, tapi saya yakin mereka (individu yang sangat cerdas yang selalu memikirkan hal ini) melakukannya untuk alasan yang bagus saat itu (kembali ke .net 2.0). Bisakah pembicaraan terjadi dan mungkin ini akan berubah tentu saja .. Tetapi faktanya adalah orang-orang yang meningkatkan ke runtime baru harus melakukan beberapa pekerjaan. Ini bukan klik tombol di ui mewah dan ada pekerjaan yang cocok untuk mereka .. Tetapi pada saat yang sama, saya setuju dengan Anda bahwa memutakhirkan ke kerangka kerja baru harus lebih mudah daripada pergi dan mengganti banyak jenis.

itu masalahnya: itu tidak dilihat sebagai 'runtime baru'. Jika itu masalahnya, seperti yang sudah saya bahas, itu tidak akan menjadi masalah. Namun Microsoft memiliki gagasan bahwa CoreFX yang menargetkan dll harus bekerja pada .NET penuh juga, jadi tidak ada kerangka kerja baru. Untuk pengelola perpustakaan yang menargetkan .NET penuh juga, dengan fungsionalitas yang tidak ada di CoreFX (jadi banyak perpustakaan di luar sana saat ini) sangat 'menyenangkan' karena mereka harus mempertahankan 2 versi. Bukan 2 atau 3 #ifdevs dan masalahnya terpecahkan, tetapi banyak dari mereka. Mungkin berbeda untuk Anda karena Anda mungkin dapat menagih klien Anda untuk jam yang harus Anda habiskan untuk mengubah apis. Ini berbeda ketika Anda membuat sistem tujuan umum yang digunakan oleh banyak orang.

Jika dukungan kerangka kerja kompak adalah pedoman apa pun, mendukung ORM di .net penuh dan CoreCLR akan menghabiskan banyak waktu, banyak frustrasi dan sebenarnya tidak terlalu banyak diperoleh: Anda tidak akan mendapatkan fitur baru, Anda hanya mengatasi _absence_ dari mereka .

(dan sebelum seseorang memulai dengan: "tapi itu berjalan di linux, Anda akan mendapatkannya": barang-barang kami berjalan di Mono sejak bertahun-tahun. Jadi tidak, itu bukan fitur baru untuk didapatkan, itu sudah ada di sana).

JualMeThisFramework. Ah kenapa aku malah repot.

tetapi apa pun yang dibangun sejak saat itu tergantung pada kelas dasar sebagai gantinya

_cough_ Linq-to-SQL DataContext _cough_

Seperti, memang, banyak ORM non-MS, maka masalahnya. Untuk necis kita hanya sedikit
peluru dan bermigrasi ke DbConnection. Jika kita punya waktu lagi, aku
akan sangat menyarankan MS menggunakan [Usang] ketika mereka sesuatu yang usang. Tetapi:
kita tidak bisa mengubah masa lalu.

Ini _adalah_ masalah yang sangat menyakitkan untuk dipecahkan, terutama karena sebagian besar
penulis perpustakaan perlu melanjutkan dengan kedua API (mengkompilasi satu cara untuk
net40 dll, dan cara lain untuk DNX). Saya memposting sebelumnya kekacauan yang mengerikan
yang necis gunakan untuk melakukan ini: tidak cantik, dan tidak sesederhana

jika.

Pada 27 Nov 2015 20:07, "Natan Vivo" [email protected] menulis:

Satu fakta penting untuk dipertimbangkan dalam diskusi ini adalah bahwa IDb*
antarmuka tidak digunakan lagi sebagai API untuk ADO.NET di .NET 2.0 satu dekade lalu
ketika kelas dasar diperkenalkan. Mereka tidak ditandai usang, tapi
apa pun yang dibangun sejak saat itu tergantung pada kelas dasar.
Penyedia App.config dan dukungan string koneksi muncul dalam pikiran.

Jika Anda memiliki kode yang bergantung pada antarmuka tersebut, Anda sedang mengkode terhadap a
API yang sangat usang tanpa dukungan untuk hal-hal seperti metode async, yang berarti
Anda tetap harus memperbaruinya jika Anda ingin orang tetap menggunakannya.


Balas email ini secara langsung atau lihat di GitHub
https://github.com/dotnet/corefx/issues/3480#issuecomment -160198453.

Saya gagal melihat intinya dengan metode async yang tidak dapat ditambahkan karena menggunakan antarmuka. Anda bisa membuat antarmuka baru untuk metode async. IAsyncDbCommand , IAsyncDataReader dll. Kemudian Anda dapat membuat kelas dasar mengimplementasikan kedua jenis antarmuka.

Pengguna ADO.NET menggunakan versi async atau versi sinkron, bukan keduanya. Jadi itu akan berhasil dengan sangat baik.

Untuk pengembang perpustakaan, tidak masalah jika fungsionalitas tumbuh dan antarmuka tetap sama. Bukankah itu tujuannya? Perkenalkan antarmuka baru untuk fungsionalitas baru. Bekerja dengan kelas dasar hanya menyebalkan.

Bisakah saya meringkas utas di sini?

Beberapa pakar komunitas independen yang diakui tentang perangkat data .NET,
termasuk beberapa penulis dan pengelola ORM memberi tahu Anda - cukup
jelas - bahwa ini mewakili serangkaian masalah yang signifikan. Saya tidak berpikir
salah satu dari kita tidak mengetahui seluk-beluk, atau naif pemrograman
prinsip, dan kebanyakan jika tidak semua dari kita tahu semua cerita belakang baik-baik saja,
karena kami ada di sana pada saat itu.

Tanggapan resmi tampaknya "sepertinya baik-baik saja bagi kami, dan EF senang".
Ya, kami tahu itu, karena keputusan sudah dibuat sejak awal.

Yah, kita semua telah menyatakan pendapat kita, bahkan jika itu tidak membuahkan hasil.
Pada 27 Nov 2015 20:41, "Jonas Gauffin" [email protected] menulis:

Saya gagal melihat intinya dengan metode async yang tidak dapat ditambahkan sebagai
hasil dari penggunaan antarmuka. Anda bisa membuat antarmuka _baru_ untuk
metode asinkron. IAsyncDbCommand, IAsyncDataReader dll. Maka Anda bisa
membuat kelas dasar mengimplementasikan kedua jenis antarmuka.

Pengguna ADO.NET menggunakan versi async atau sinkron
versi, bukan keduanya. Jadi itu akan berhasil dengan sangat baik.

Untuk pengembang perpustakaan, tidak masalah jika fungsionalitas tumbuh dan
antarmuka tetap sama. Bukankah itu tujuannya? Perkenalkan baru
antarmuka untuk fungsionalitas baru. Bekerja dengan kelas dasar hanya menyebalkan.


Balas email ini secara langsung atau lihat di GitHub
https://github.com/dotnet/corefx/issues/3480#issuecomment -160201361.

Teman-teman.. perbarui kode Anda dan temukan versi utama Anda. Selesai.

Ya, tetapi tidak ada alasan Anda tidak dapat pollyfill antarmuka itu dengan arahan kompiler saat menargetkan core. Saya telah melakukannya dengan beberapa paket pcl kami.

Saya pikir Microsoft perlu menegaskan kembali bahwa inti tidak penuh tetapi itu masih tidak membantu .. Saya pikir Microsoft perlu membersihkan beberapa antarmuka untuk jujur. Ada posting blog baru-baru ini di mana ada antarmuka yang sangat tidak konsisten dan Anda tidak pernah tahu mana yang harus dipilih .. Saya pikir mendefinisikan antarmuka async kedua menyebalkan. Akan lebih baik jika semuanya async..

Akan lebih baik jika kerangka kerja lengkap telah dilalui untuk memastikan hal-hal yang perlu ditandai sebagai usang adalah... Dan dirilis sebagai 4.6.2

@mgravell +100. Bagus, 100% setuju.

Berapa banyak yang benar-benar terpengaruh? Kita berbicara tentang coreclr di sini? Desktop .NET akan hidup selama bertahun-tahun yang akan datang sampai coreclr dapat mengejar ketinggalan. Tepat bagi mereka yang mengeluh, apa yang Anda pertanggungkan kerugian di sini? Banyak orang pada dasarnya mengatakan ini adalah akhir dunia.

@leppie Memang, itu akan ada selama bertahun-tahun. Dan kami juga harus mempertahankan peretasan dan solusi ini dalam kode kami selama bertahun-tahun yang akan datang. Titik pertikaian di sini adalah penghapusan jembatan umum antara keduanya. Beban kerja itu telah dialihkan ke semua pengembang perpustakaan, bukan di BCL. Saya memahami kedua sisi pro dan kontra antarmuka, tetapi saya tidak mengerti sikap "ini kecil, lanjutkan" dari beberapa orang di sini.

Mari kita berterus terang di sini: Jika semua konsumen perpustakaan harus melakukan hal yang sama, itu harus di BCL . Perdebatannya adalah "apa bentuknya?"

Di sisi positifnya untuk menghapus antarmuka, ada mekanisme pembuatan versi _tambahan_ dengan model pengemasan baru yang sekarang sedang dimainkan: kelas mana yang tersedia di X, Y dan Z sekarang jauh lebih baik didukung oleh perkakas. Misalnya dotnet5.2 vs 5.4 saat ini. Tapi kemudian ada kekurangan di sana juga. Misalnya SqlClient masih belum sampai pada titik mengimplementasikan antarmuka seperti sekarang (lihat dotnet/runtime#14302 dan dotnet/runtime#15269), dan mengingat apa yang dikatakan @YoungGah (kecuali saya salah membaca) kami menunggu pada 5.4 atau 5.5 untuk tingkat dukungan yang sama untuk skema, sisipan massal, dll.

Jadi apa yang terjadi dengan 5.6 (1,5)? Jika lebih banyak anggota ditambahkan ke kelas abstrak, setiap penyedia data diharapkan untuk mengikuti target bergerak yang dapat berubah dengan setiap orang yang bergerak? Setiap konsumen perlu melakukan penentuan versi pada fitur yang tersedia di masing-masing? Kita perlu mengkompilasi versi Majelis untuk setiap versi platform yang bergerak maju agar sesuai dengan basis abstrak kelas yang dilewati? Bagaimana semua ini bekerja ke depan dengan penambahan tidak 100% jelas. Antarmuka yang tidak berubah jauh lebih jelas. Di atas ini adalah dokumentasi: fitur, metode, dll. mana yang tersedia di mana versi _dan platform_ akan menjadi titik sakit yang sangat besar bagi semua penulis perpustakaan yang bergerak maju. Kekhawatiran itu hanya semi-terkait di sini, tetapi dalam permainan.

Untuk saat ini, saya dengan cemas menunggu pembaruan dalam 2 minggu ke depan. Ketakutan saya adalah itu akan efektif, karena perpesanan sepanjang waktu adalah: "Kami melakukan X karena berfungsi untuk SQL dan Entity Framework, dan itu cukup baik" - tanpa menggunakan kata-kata itu. Frustrasi di pihak penulis perpustakaan, bagi saya, adalah kurangnya kemajuan (baik dalam kode dan diskusi) di bidang ini selama berbulan-bulan sekarang.

100% setuju.

Ketika saya telah merancang v2 (dan lebih tinggi) dari SqlFu (ORM Mikro saya), saya harus memutuskan di mana harus melampirkan metode ekstensi: ke DbConnection/DbCommand atau ke antarmuka. Saya menemukan ini dan saya memutuskan untuk mengikuti kelas abstrak.

Oleh karena itu, saya tidak terpengaruh, meskipun saya terpengaruh oleh penghapusan IDataReader , karena MS dalam kebijaksanaan mereka memutuskan untuk tidak memperjelas antarmuka mana yang harus diperlakukan sebagai usang dan mana yang tidak. Tetapi dalam kasus saya, tidak sulit untuk mengganti antarmuka.

Namun, saya melihat nilai memiliki antarmuka khusus dan saya tidak berpikir itu sulit bagi MS untuk menyimpan/menambahkannya kembali. Jika mereka memutuskan antarmuka lama tidak dirancang dengan baik, baiklah! Rancang yang baru agar lebih spesifik. Setidaknya di masa depan kita tidak harus berurusan dengan masalah yang sama.

(Ini adalah minggu Thanksgiving di AS, jadi tanggapan dari Microsoft akan sangat terbatas sampai mereka kembali ke kantor minggu depan)

Hanya ingin mengulangi - agar tidak kehilangan saran/bug bagus di utas ini, jika Anda memiliki masalah dengan kelas dasar/area permukaan saat ini, dan/atau cara versi mereka ke depan, silakan ajukan masalah baru, biarkan diskusi ini hanya tentang antarmuka v1.

@NickCraver Mirip dengan versi ke versi kompatibilitas .NET Framework, tidak akan ada perubahan yang melanggar antara versi .NET Core luas permukaan. Misalnya, penambahan anggota abstrak ke kelas dasar akan menjadi contoh perubahan yang _tidak_ akan dilakukan.

@davkean seberapa yakin Anda bahwa itu tidak akan terjadi? Mengingat bahwa kita melihat area permukaan yang tidak lengkap dan tidak ada jaminan bahwa itu akan berubah, sulit untuk percaya bahwa bagian yang hilang tidak akan muncul nanti jika sama sekali. Namun, saya pikir tidak ada perubahan yang melanggar adalah _more_ hal penting, yang saya yakin sebagian besar penulis perpustakaan di sini juga akan berasumsi. Itu berarti lebih penting lagi barang-barang ini dirawat dengan baik sebelum RTM hits.

Sebagai catatan ada masalah terpisah yang diajukan di area permukaan, lihat dotnet/runtime#14302 dan dotnet/runtime#15269 dengan pembaruan terbaru dari Microsoft masing-masing pada 25 September dan 2 Oktober - meskipun meminta pembaruan dan aktivitas beberapa kali setelah itu. Itu 2 bulan dan 2 rilis yang telah berlalu, dengan diam. Ini meskipun dotnet/runtime#14302 menjadi masalah paling aktif dalam repo ini (dan yang ini baru saja menjadi yang ke-2). Bisakah Anda memahami kekecewaan kami?

Saya benar-benar yakin kami tidak akan membuat perubahan yang melanggar, tim Data Common sedang mempertimbangkan untuk membuatnya tanpa memperkenalkan anggota abstrak.

@NickCraver Maaf, @YoungGah memberikan pembaruan di atas tentang mereka, saya akan memastikan dia memperbarui masalah dengan kemajuannya. Banyak MS masih membiasakan diri dengan _bekerja di tempat terbuka_ ini, itu akan menjadi lebih baik dari waktu ke waktu - terima kasih telah menghubungi kami.

@niemyjski

dnx adalah kerangka kerja/runtime yang benar-benar baru

Jika Anda berpikir dnx runtime dan pustaka corefx terwujud begitu saja, Anda benar-benar meremehkan waktu yang diperlukan untuk mengembangkannya dari awal. Fakta bahwa pustaka CoreFx berjalan pada .NET Framework lengkap seharusnya memberi Anda petunjuk bahwa, tidak, itu tidak sepenuhnya baru.

Jika tidak memiliki beberapa antarmuka, tangani itu ... dengan arahan kompiler.

Ya, tetapi tidak ada alasan Anda tidak dapat pollyfill antarmuka itu dengan arahan kompiler saat menargetkan core.

Jika Anda repot membaca komentar sebelum terbang ke utas ini, Anda akan tahu bahwa a) ada alasan dan b) ini adalah strategi yang tidak dapat dijalankan yang rusak untuk antarmuka inti BCL.

@nvivo

Satu fakta penting untuk dipertimbangkan dalam diskusi ini adalah bahwa antarmuka IDb* tidak digunakan lagi sebagai API untuk ADO.NET di .NET 2.0 satu dekade lalu ketika kelas dasar diperkenalkan.

Jika itu masalahnya maka Anda tidak akan membuka masalah yang menyuruh mereka untuk kembali menggunakan antarmuka yang Anda ketahui sudah ditinggalkan oleh kelas dasar satu dekade yang lalu. Cara Anda mengomunikasikan API tidak digunakan lagi adalah dengan menggunakan atribut [Obsolete] yang merupakan satu-satunya tujuan yang ada. Jika tidak dikomunikasikan secara luas, itu tidak ditinggalkan terlepas dari apa yang Anda pikirkan sekarang. Fakta bahwa sebagian besar ORM non-MS .NET bergantung pada mereka harus memberikan indikasi bahwa penghentiannya dikomunikasikan dengan buruk, jika ada.

Jika Anda memiliki kode yang bergantung pada antarmuka tersebut, Anda membuat kode terhadap API yang sangat usang tanpa dukungan untuk hal-hal seperti metode async, yang berarti Anda tetap harus memperbaruinya jika Anda ingin orang tetap menggunakannya.

Seorang pembuat jerami palsu - yang satu tidak menyiratkan yang lain. Kami telah menambahkan dukungan untuk async API, dan tidak, menambahkannya tidak merusak basis kode Pelanggan yang ada, juga tidak perlu mengubah API yang ada.

Oke, keseluruhan membuat awal yang bersih ini bagus, tetapi bolehkah saya mengajukan satu pertanyaan: Kompromi apa yang telah dibuat untuk mendukung kerangka kerja Anda sendiri? Kengerian masa lalu apa yang telah dimigrasikan karena dibutuhkan untuk menjalankan, katakanlah, Entity Framework?

Akan sangat disayangkan untuk membuat MicroORM menghilang, mereka membuat kode .Net agak berkinerja (EF adalah binatang yang tidak dapat digunakan untuk aplikasi di mana 500ms untuk memuat beberapa baris tidak dapat diterima).

Adapun antarmuka vs kelas dasar: kelas dasar sangat bagus selama semua yang dapat digunakan kembali adalah virtual. Misalnya salah satu keputusan desain yang paling menjengkelkan di WCF adalah penggunaan berlebihan kelas tertutup yang berisi banyak fungsi. Katakanlah Anda harus membuat tweak kecil dengan cara mengatakan pesan XML ditangani (karena: interop). Alih-alih mewarisi dan mengganti satu fungsi kecil, Anda harus mengimplementasikan kembali. Dalam contoh WCF, S dalam SOLID dilewati sehingga Anda biasanya dibiarkan mengimplementasikan antarmuka besar tanpa ada tes yang diperlukan untuk memastikan kualitas produksinya.

Jadi: kelas dasar yang bisa kita adaptasi adalah hal yang baik.

Saya benar-benar yakin kami tidak akan membuat perubahan yang melanggar, tim Data Common sedang mempertimbangkan untuk membuatnya tanpa memperkenalkan anggota abstrak.

@davkean Itu tidak mungkin dijamin, dan Anda tahu itu. ADO.NET adalah subsistem untuk berkomunikasi dengan perangkat lunak pihak ke-3 dengan berbagai macam fitur, yang diekspos melalui API umum dengan beberapa titik ekstensi. Banyak hal berubah, bahkan di tanah basis data, dan perubahan ini menjalar ke API yang digunakan untuk berkomunikasi dan menggunakan layanan basis data eksternal ini. Selain itu: perubahan perilaku _is_ juga merupakan perubahan yang melanggar. Dan kami telah melihatnya juga di ADO.NET (misalnya tentang penanganan kesalahan) dalam beberapa tahun terakhir.

Seluruh ADO.NET API penuh dengan efek samping dari perubahan tersebut, seringkali didorong oleh SQL Server; hampir tidak ada hal yang dirancang secara umum dan kemudian dipindahkan ke SQL Client, tetapi sebaliknya (misalnya tidak banyak, jika ada, fitur di kelas dasar yang diabaikan oleh SqlClient). Ditambah lagi hal-hal yang dibutuhkan oleh pihak ke-3 tidak pernah berhasil masuk ke API.

Jadi singkatnya, ini adalah API yang, pada awalnya dengan .NET 1.0 memiliki desain umum (yang terbukti sangat cacat di banyak area) dan yang sejak itu telah ditambal dengan fitur kiri dan kanan untuk mengatasi perubahan dalam pemandangan. _Sebagian besar_ masih ada di API (jika tidak semua). Dan sekarang Microsoft akan menghapus satu: antarmuka.

Sama sekali _tidak ada_ yang diperoleh dengan menghapus bagian acak dari API: tidak ada fitur yang ditambahkan melalui ini (Anda dapat menghabiskan waktu untuk itu alih-alih mendorong kembali ke sini misalnya), tetapi kode yang memanfaatkan bagian API itu _will_ tidak berfungsi. Jika titik di balik semua pemindahan keju ini adalah 'untuk memulai dari awal' maka tentu saja, lakukan, tetapi lakukan dengan mendesain ulang API untuk menjadikannya API tujuan umum yang sebenarnya, singkirkan _semua_ cruft yang telah menumpuk selama bertahun-tahun .

Tapi itu tidak dilakukan. Tidak ada yang bertanya-tanya mengapa, kita semua tahu mengapa. Kita juga tahu bahwa jika sebuah tim dalam MS akan sangat dirugikan oleh penghapusan antarmuka, mereka tidak akan pernah dihapus sejak awal.

Jika Microsoft dapat menambahkan fungsionalitas baru melalui kelas dasar sehingga penyedia pihak ketiga secara otomatis menerapkan 'bentuk' fitur (seperti dengan Async, di mana metode async kembali ke metode sinkronisasi jika penyedia tidak menerapkannya), bagus: itu berarti kami pengembang ORM pihak ke-3 (dan menghadapinya: banyak pengembang yang mengakses API _Anda_ melalui kode ORM pihak ke-3 (mikro)) dapat dengan mudah menargetkan satu kelas dan hanya itu.

Tapi itu tidak menjamin Anda akan melakukannya. Misalnya tidak ada seorang pun di dalam Microsoft yang pernah repot dengan fitur khusus untuk Oracle atau PostgreSql yang akan ditambahkan ke ADO.NET. Misalnya penggunaan UDT, pohon Dokumen, beberapa hasil melalui kursor, setiap penyedia ADO.NET harus menemukan cara mereka sendiri untuk menangani fitur-fitur ini. Bagaimana jika (kapan?) SQL Server mendapatkan fitur pohon dokumen misalnya dengan JSON docs, apakah ADO.NET akan diperbarui kemudian dengan API baru untuk itu? Seperti yang telah Anda lakukan di masa lalu dengan pelaporan kesalahan dari penyedia ADO.NET?

Anda tidak dapat membuat jaminan seperti itu, dan tidak bijaksana untuk menyatakan di sini bahwa MS tidak akan merusak apa pun di masa mendatang. Mereka selalu memiliki dan kadang-kadang mereka bahkan harus: bagaimanapun juga setiap API memiliki kekurangan, dan ADO.NET penuh dengan kekurangan itu; satu cara atau yang lain suatu hari seseorang akan 'memperbaiki' mereka.

Jadi, untuk rekap: antarmuka adalah bagian dari ADO.NET seperti juga bagian yang rusak di tempat lain di API adalah bagian dari ADO.NET. Itu tidak dihapus untuk memperbaiki API, API juga tidak di-refactored untuk menjadikannya API tujuan yang lebih umum: dibiarkan apa adanya, dengan beberapa elemen dihapus seperti DataSet/Tabel tergantung elemen karena ini tidak porting (dan ada adalah masalah lain yang memperdebatkannya dengan kemajuan serupa), kecuali... antarmuka dihapus.

Dari sudut pandang itu saja sudah tidak masuk akal.

@mythz

Jika itu masalahnya maka Anda tidak akan membuka masalah yang menyuruh mereka untuk kembali menggunakan antarmuka yang Anda ketahui sudah usang

Anda tidak mungkin membaca OP dan memahaminya. Diskusi-diskusi ini menjadi terlalu religius dan Anda hanya berasumsi hal-hal yang tidak dikatakan siapa pun.

Saya membuka masalah ini karena saya yakin antarmuka lebih baik dalam menggambarkan api dan membantu pengujian. Jika sudah selesai, saya tidak berpikir mereka harus kompatibel dengan api berusia 15 tahun yang memiliki masalah. Kompatibilitas mundur tidak pernah menjadi masalah sampai kalian memindahkan diskusi ke sana.

Bukannya saya percaya bahwa segala sesuatunya harus hancur hanya demi itu. Tapi versi antarmuka adalah masalah masa lalu. Jika corefx mengubah sesuatu di antara versi utama, versi utama yang diharapkan memiliki perubahan yang melanggar. Jika mereka merusak antarmuka antara versi minor, itu hanya kecerobohan.

Kami telah menambahkan dukungan untuk async API

Anda tidak dapat menambahkan api async di atas api sinkronisasi. Jika Anda melakukannya menggunakan IDbConnection atau IDbCommand, Anda salah melakukannya. Jika Anda tidak menggunakan antarmuka ini, maka Anda sebenarnya tidak ada gunanya mempertahankan kompatibilitas mundur apa pun dengannya.

Kami telah menambahkan dukungan untuk async API

Anda tidak dapat menambahkan api async di atas api sinkronisasi. Jika Anda melakukannya menggunakan IDbConnection atau IDbCommand, Anda salah melakukannya. Jika Anda tidak menggunakan antarmuka ini, maka Anda sebenarnya tidak ada gunanya mempertahankan kompatibilitas mundur apa pun dengannya.

Di ADO.NET itulah yang mereka lakukan: metode Async secara default kembali ke varian sinkronisasi. Dengan cara ini semua penyedia ADO.NET yang tidak mendukung Async (baca: semuanya kecuali SqlServer saat ini) tidak perlu mengimplementasikan hal-hal yang tidak mereka dukung: Kode pihak ketiga di ORM yang menawarkan Async api dapat memprogram melawan metode Async di ADO.NET dan jika penyedia ado.net tidak mendukung async, tidak ada yang benar-benar tahu. Anda akan tahu karena lebih lambat, tapi selain itu.

Sekarang ini juga merupakan ilustrasi yang baik tentang tidak adanya 'desain' atau arsitektur umum dalam ADO.NET: ada _no_ cara untuk membuat savepoint transaksional di API umum. Meskipun hampir _semua_ database mendukungnya dengan metode 'Simpan(string)' pada kelas turunannya dari DbTransaction. Semua kecuali OleDbTransaction (karena MS Access tidak mendukungnya, setidaknya itulah kecurigaan saya).

Ini tidak mudah, tetapi tidak ada yang mengatakan itu mudah. Masalah ini bukanlah hal baru, OleDB dan ODBC telah menanganinya selama bertahun-tahun, JDBC telah menemukan cara untuk menyelesaikannya, Microsoft tidak perlu menemukan kembali roda untuk mengatasi hal-hal seperti ini. Ini juga tidak unik untuk ranah DB: misalnya setiap kartu video di luar sana mendukung subset fitur yang berbeda melalui API-nya, yang diekspos ke pengembang melalui Direct3D/X. Sebenarnya menarik bagaimana desain berjalan di dunia lain ini: API dirancang, dan pihak-pihak yang perlu mendukungnya (driver JDBC, penulis driver OleDB, dll.) harus mengimplementasikannya. Driver Anda tidak akan mendukung X? Driver Anda tidak sesuai dengan X. "Oracle tidak mendukung ADO.NET v10". Tak seorang pun di dalam Oracle ingin membacanya. Sebaliknya SqlClient memimpin, dan apa yang jatuh dari gerobak ditambahkan ke ADO.NET dan hanya itu.

Di ADO.NET itulah yang mereka lakukan: metode Async secara default kembali ke varian sinkronisasi.

Tidak. API mengekspos metode asinkron yang mundur ke metode sinkronisasi secara default, tetapi penyedia menimpa dengan operasi asinkron nyata. Apa yang @mythz nyatakan adalah bahwa dia menggunakan IDbCommand dan IDbConnection dan melakukan itu.

Ini tidak mungkin, titik. Jika Anda melakukannya, Anda tidak melakukannya dengan benar atau Anda tidak menggunakan antarmuka. Anda tidak dapat menemukan async jika api yang mendasarinya tidak async.

Tidak. API mengekspos metode asinkron yang mundur ke metode sinkronisasi secara default, tetapi penyedia menimpa dengan operasi asinkron nyata. Apa yang @mythz nyatakan adalah bahwa dia menggunakan IDbCommand dan IDbConnection dan melakukan itu.

Tidak ada penyedia resmi yang melakukan itu kecuali SqlClient, semua yang lain, misalnya ODP.NET, tidak mengimplementasikan segala bentuk kode async dan dengan demikian kode panggilan jatuh kembali ke varian sinkronisasi (metode async di DbDataReader/DbCommand dll. yang benar-benar mengeksekusi kode sinkronisasi ). jadi kode pengguna memanggil varian asinkron, yang berada di bawah kap melakukan operasi sinkronisasi. Yang menghasilkan tidak ada async yang dilakukan dalam praktik (karena semua kode hanya disinkronkan dalam praktik). Mungkin penyedia devart mengimplementasikan api async dalam implementasi mereka sendiri, tidak yakin.

Bagaimanapun, ini bukan tentang melakukannya dengan benar, ini tentang pembuatan versi API.

@nvivo

Saya membuka masalah ini karena saya yakin antarmuka lebih baik dalam menggambarkan api dan membantu pengujian. Jika sudah selesai, saya tidak berpikir mereka harus kompatibel dengan api berusia 15 tahun yang memiliki masalah. Kompatibilitas mundur tidak pernah menjadi masalah sampai kalian memindahkan diskusi ke sana.

Oke, jadi Anda tahu antarmuka inti ADO.NET tidak digunakan lagi 10 tahun yang lalu, dengan semuanya dipindahkan ke kelas dasar, namun Anda pikir mereka harus mengabaikannya sekarang dan kembali ke antarmuka, secara kebetulan menggunakan nama yang sama dengan antarmuka yang ada, tetapi antarmuka yang ada seharusnya tidak ada lagi, karena kompatibilitas ke belakang tidak diperlukan bukan? tentu, terdengar sah.

Jika Anda ingin memajukan platform, Anda mengembangkan API dari waktu ke waktu dan mendukungnya secara paralel, memberi semua orang kemampuan untuk juga mendukung API paralel dan memungkinkan mereka untuk merencanakan jalan mereka dan Pelanggan mereka. Merobeknya tanpa peringatan tidak perlu merusak ekosistem yang mengandalkannya dan mendorong kompleksitas ke setiap ketergantungan hilir.

Anda tidak dapat menambahkan api async di atas api sinkronisasi. Jika Anda melakukannya menggunakan IDbConnection atau IDbCommand, Anda salah melakukannya. Jika Anda tidak menggunakan antarmuka ini, maka Anda sebenarnya tidak ada gunanya mempertahankan kompatibilitas mundur apa pun dengannya.

Saya berharap Anda berhenti mencemari utas ini dengan komentar tentang hal-hal yang jelas-jelas tidak Anda ketahui. Baca kode sumber jika Anda ingin tahu bagaimana Async API diterapkan - dan berhenti menyebarkan kebohongan secara membabi buta. Tidak mungkin bagi perpustakaan pihak ketiga untuk memperluas antarmuka System.Data. Kami menyediakan API implementasi-agnostik yang untuk mendukung setiap RDBMS utama, memperlihatkan ketergantungan minimum yang diterapkan oleh setiap penyedia ADO.NET dalam API yang menghadap eksternal - yaitu antarmuka System.Data inti. Async API adalah metode ekstensi dari IDbConnection yang di balik layar memanfaatkan async API pada penyedia ADO.NET konkret yang memiliki dukungan untuk mereka. Secara internal sudah ada ketergantungan nyata pada setiap penyedia ADO.NET yang didukung, terlepas dari dukungan async. Saran Anda bahwa kami "tidak ada gunanya mempertahankan kompatibilitas mundur dengan mereka" tidak berpengalaman dan sama sekali tidak berdasar.

Izinkan saya menanyakan hal ini kepada pihak Microsoft (cc @davkean @YoungGah): Katakanlah ini adalah dunia yang sempurna dan tidak ada yang pernah muncul. Kapan _do_ Anda ingin merusak sesuatu? Versi utama seperti 6.0? Lain waktu? Argumen terhadap antarmuka adalah bahwa mereka tidak versi. Ya, itu valid - tetapi _jika kita juga tidak mengubah kelas abstrak_, itu juga merupakan poin yang bisa diperdebatkan. Jadi ... bisakah kita mendapatkan kejelasan di sana?

Tindak lanjut:
Jika jawabannya ya (pada beberapa titik pasca-RTM akan ada perubahan), lalu jeda seperti apa yang akan kita lihat? Tambahan, metode baru? Jika saya mewarisi kelas dasar untuk penyedia saya, lalu apa yang terjadi ketika Anda menambahkan metode yang saling bertentangan yang digunakan orang, dll.?

Jika jawabannya tidak (tidak pernah): mengapa tidak menambahkan antarmuka saja?

Utas ini agak macet saat membahas _sekarang_ - yang sebagian besar merupakan hal yang baik karena hal ini perlu diperbaiki secepatnya. Setiap penulis perpustakaan di sini tahu betapa sulitnya mendapatkan sesuatu setelah rilis dilakukan, dan itulah sebabnya kami mendorong begitu keras. Sayangnya, kurangnya rencana yang jelas untuk _penambahan dan perubahan _masa depan_, jika ada, membuat lebih banyak argumen yang kurang informasi.

Apa rencana untuk masa depan?

Kita seharusnya tidak memaksakan implementasi melalui kelas abstrak dalam kasus ini. IMO

Microsoft tidak akan membuat perubahan yang melanggar untuk .NET 4.5. Itu bagian dari Windows. Kompatibilitas adalah raja.

Microsoft dapat membuat perubahan yang merusak .NET Core yang tidak berdampak pada 4.5. Saya ragu mereka akan memposting 1.0 RTM pada level rendah seperti ADO.NET, tetapi bilahnya lebih rendah. Ini bukan bagian dari Windows dan versi .NET Core dapat digunakan secara berdampingan.

Kelas abstrak dapat diubah - itu tidak melanggar. Cukup tambahkan metode yang virtual dengan implementasi default. Itu sudah dilakukan dengan metode async ADO.NET. Dengan diperkenalkannya .NET Core, saya yakin perubahan dalam kelas bersama perlu dilakukan bersamaan dengan rilis .NET 4.5 untuk menjaga kompatibilitas. Seseorang perbaiki saya jika itu salah dan hanya berlaku untuk antarmuka :grin:

@FransBouma

Tidak ada penyedia resmi yang melakukan itu kecuali SqlClient, semua yang lain, misalnya ODP.NET, tidak mengimplementasikan segala bentuk kode async dan dengan demikian kode panggilan jatuh kembali ke varian sinkronisasi

Anda benar, tapi itu bukan masalah dengan API, dan lebih banyak kemalasan atau kurangnya pemahaman oleh para pelaksana. Konektor MySql misalnya mengimplementasikan kembali semua metode async mereka dengan membuat TaskCompletionSource dan menyelesaikannya dengan metode sinkronisasi, yang konyol. Mereka hanya bisa menghapus setengah dari basis kode mereka dan tetap dengan perilaku yang sama.

Tidak mengatakan bahwa antarmuka akan menyelesaikannya, tetapi tidak memiliki perilaku default untuk async setidaknya akan membuat beberapa dari mereka memikirkan hal ini. Fakta bahwa 90% orang yang sangat teknis tidak memahami operasi asinkron juga tidak membantu.

Kelas abstrak dapat diubah - itu tidak melanggar. Cukup tambahkan metode yang virtual dengan implementasi default. Itu sudah dilakukan dengan metode async ADO.NET.

Ini melanggar. Ini melanggar untuk semua perpustakaan yang mensubklasifikasikan implementasi ini tanpa mengetahui itu ditambahkan dan orang-orang kemudian mengkonsumsi pemikiran ini. Oh implementasi ini sekarang didukung dengan postgresql BAM ERROR wtf terjadi ...

Implementasi paksa untuk abstraksi db salah.

Tidak masalah apakah itu antarmuka atau kelas dasar. Akan ada perubahan yang melanggar. Tetapi implementasi paksa yang telah ditentukan sebelumnya salah.

Polimorfisme tidak bekerja seperti itu. Anda tidak dapat mengganti metode tanpa mengetahuinya. Jika referensi Anda adalah DbConnection dan Anda memanggil QueryAsync, itu hanya akan memanggil metode itu atau apa pun yang telah diganti. Metode yang disebut QueryAsync yang kebetulan sudah ada di subkelas tidak akan dipanggil.

Anda bingung mengganti ayat metode yang menyembunyikannya dengan nama yang sama.

@JamesNK

Jika metode didefinisikan sebagai abstrak, tidak ada implementasi di kelas dasar. Ini melanggar kontrak untuk pihak ke-3 karena mengharuskan mereka untuk menambahkan implementasi di sub kelas.

Jika Anda membuat metode virtual sehingga dapat ditimpa, maka implementasi ada di kelas dasar yang tidak masuk akal bagi subkelas. Ini masih melanggar karena ada implementasi yang tidak diterapkan oleh penulis perpustakaan. Tentu aplikasi Anda dapat dikompilasi, dan semuanya keren, tetapi seseorang memanggil metode itu, dan itu tidak valid untuk subkelas. Itu salah. Itu adalah implementasi paksa yang bukan milik sub kelas.

Jadi, kelas abstrak tempat implementasi bisa ada yang bukan milik sub kelas. Atau antarmuka di mana tidak ada implementasi default untuk pihak ke-3.

@phillip-haydon itu sebabnya diimplementasikan sebagai metode virtual, bukan metode abstrak.

Anda dapat menambahkan hal-hal itu hanya akan merusak subclass yang sudah memiliki anggota dengan tanda tangan yang sama (nama/args). Jika argumennya berbeda, itu bisa menimbulkan bug halus jika pengembang salah mengira kelebihannya.

Itu adalah implementasi paksa yang bukan milik sub kelas.

Kalau begitu jangan taruh di sana.

@jamesnk

Jangan taruh di sana. Itu sebabnya kami memperdebatkan penghapusan antarmuka.

Menjadikannya virtual tidak menyelesaikan masalah. Seharusnya tidak ada implementasi yang ditentukan sebelumnya. Akhir dari cerita

@JamesNK Dalam hal ini kami tidak meletakkannya di sana, _Microsoft_ meletakkannya di sana dengan memasukkannya ke dalam abstrak. Menambahkan metode yang dianggap berfungsi di _all_ penyedia yang pernah mewarisi Saya tidak benar-benar melihat berjalan lancar secara efisien bahkan jika tidak melanggar secara teknis (saya akan mengakui peringatan kompilasi "harus menggunakan baru" _secara teknis_ tidak rusak). Tidak akan ada implementasi bersama atau langsung dibagikan dalam _kebanyakan_ kasus. Jadi apa alternatifnya? throw new NotImplementedException() di dalam virtual itu? Itu bukan argumen untuk itu sejak awal, itu penuh dengan lebih banyak masalah (runtime).

Mari kita lihat hari ini: Saya lebih suka melihat IDbAsyncConnection ditambahkan ketika penyedia mendukungnya daripada sekelompok metode yang sinkron di bawah penutup yang mengarah ke kebingungan dan inefisiensi, yang kita miliki hari ini pada ini abstrak.

Saya lebih suka melihat IDbAsyncConnection ditambahkan ketika penyedia mendukungnya daripada sekelompok metode yang sinkron di bawah selimut yang menyebabkan kebingungan dan inefisiensi

@NickCraver +1000 untuk itu. Seperti bug ini di sini di mana tim Oracle tidak mengerti apa artinya async.

Anda bisa melakukannya dengan antarmuka. Masalah dengan mereka adalah Anda kemudian tidak dapat menerima argumen yang menuntut banyak antarmuka, misalnya saya memerlukan jenis yang baik IDbAsyncConnection dan IDbConnection. Anda kehilangan pengetikan yang kuat dan Anda harus mulai menanyakan gaya antarmuka COM yang menurut saya tidak terlalu ramah pengguna. Ini adalah alat dalam desain API yang memiliki tempatnya, tetapi saya tidak tahu apakah saya akan menggunakannya secara default.

Jika implementasi default melempar NotImplementedException maka menguncinya ke kelas dasar adalah hal yang salah untuk dilakukan. Seperti yang saya katakan, jangan taruh di sana. Jika Anda melihat seseorang melakukannya, angkat masalah.

Either way, apakah itu antarmuka atau kelas dasar abstrak, pengalaman saya menambahkan fitur baru ke perpustakaan yang awalnya tidak dirancang untuk mereka tanpa merusak dunia sangat sulit.

@JamesNK mungkin IDbAsyncConnection akan mewarisi IDbConnection sini, tetapi itu belum tentu demikian - mereka dapat berbagi anggota yang sama atau mewarisi dari basis yang sama. Misalnya di Dapper kami mungkin akan menerapkan sebagai berikut:

``` C#
dapat dihitungPertanyaan(Cnn IDbConnection ini, cmd CommandDefinition)

``` C#
Task<IEnumerable<T>> QueryAsync<T>(this IDbAsyncConnection cnn, CommandDefinition cmd)

Saya membayangkan sebagian besar perpustakaan dengan metode sinkronisasi/async akan memiliki penggunaan dan implementasi yang serupa.

_Edit:_ setelah mengetik bahwa saya menyadari betapa jauh lebih baik Async di akhir nama untuk semua ini...

ADO.NET mengalami perubahan besar berikut selama bertahun-tahun:

  1. Pada tahun 2003 (1.1) mereka membuat perubahan besar dari 1.0 dan mendesain ulang itu
  2. Pada tahun 2005 (2.0) mereka pindah ke model penyedia dengan kelas dasar yang ada saat ini
  3. Pada 2012 (4.5) mereka menambahkan dukungan async, yang sebenarnya tidak mengubah apa pun selain menambahkan metode baru yang melakukan hal yang sama secara asinkron.

Kembali ke cara mendefinisikan api 2003 adalah perubahan yang akan merusak kompatibilitas (yang tidak diinginkan orang) atau menghapus fitur yang ditambahkan dalam dekade terakhir. Tetapi menambahkan antarmuka baru ke .NET Core dengan desain saat ini _source compatible_ dengan versi .NET apa pun. Anda hanya perlu mengkompilasi ulang agar sebagian besar kode yang ditulis dalam 15 tahun terakhir berfungsi. Dan Anda tetap harus mengkompilasi ulang untuk menargetkan corefx.

API ini telah stabil untuk waktu yang lama. Itu bisa didesain ulang sebagai antarmuka jika orang mau. Seperti biasa, tidak ada masalah teknis di sini, itu bermuara pada bekas luka, preferensi dan ego.

Mengapa tidak mengembalikan antarmuka dan menandainya sebagai usang?

Meskipun ide ini dibatalkan, saya bertanya-tanya apakah perakitan netral inferfaces dapat membantu dalam situasi seperti ini, lihat ini http://davidfowl.com/assembly-neutral-interfaces/ dan kemudian implementasinya
http://davidfowl.com/assembly-neutral-interfaces-implementation/

Saya pikir antarmuka netral perakitan adalah ikan haring merah di sini; jika ada
terjadi, ini benar-benar hal yang "umum", karena "umum" ada. Ditambah lagi
diperdebatkan karena fitur tersebut menguap.
Pada 28 Nov 2015 17:38, "Shahid Khan" [email protected] menulis:

Meskipun ide ini dibatalkan, saya bertanya-tanya apakah perakitan netral
inferfaces bisa membantu dalam situasi seperti ini lihat ini
http://davidfowl.com/assembly-neutral-interfaces/ dan kemudian mereka
penerapan
http://davidfowl.com/assembly-neutral-interfaces-implementation/


Balas email ini secara langsung atau lihat di GitHub
https://github.com/dotnet/corefx/issues/3480#issuecomment -160323344.

Yang saya amati:

  • Orang-orang di balik gagasan CoreClr (kerangka kerja mengkilap baru) memiliki pola pikir yang sama sekali berbeda dari orang-orang di balik implementasinya (kompatibilitas mundur dengan basis kode berusia 15 tahun adalah raja).

Apa yang saya pikirkan:

  • Dengan menghapus antarmuka, Anda memperburuk keadaan .
  • Tidak ada yang usang sampai dihiasi dengan [Usang]. Dan tidak masalah siapa yang memikirkan apa pada suatu saat. Ini kontrak dan jika Anda tidak memuaskannya maka Anda tidak.

Apa yang saya inginkan:

  • Gunakan antarmuka sebagai permukaan dasar API daripada kelas dasar.

Apa yang saya rasakan:

  • Kami berada di akhir tahun 2015 dan membuat frustrasi dan sedih melihat orang-orang berdebat tentang ini.

antarmuka tidak dapat diversi.

Tentunya antarmuka mudah diversi dengan pewarisan antarmuka? Dan jika itu melakukan sesuatu yang sama sekali berbeda; baik itu antarmuka yang berbeda.

interface IOldInterface {}
interface INewInterface : IOldInterface {}
interface IDifferentInterface {}

class SomeClass : IOldInterface, INewInterface, IDifferentInterface
{
}

Hanya saja, jangan menyebutnya IInterfaceV2 , IInterfaceV3 itu perlu menjelaskan apa yang ditambahkannya.

Untuk menempatkan dalam konteks [Obsolete] antarmuka lama, dan menggunakan beberapa antarmuka baru dan menyebutnya apa adanya; daripada metode non-async yang tampak normal di zaman sekarang ini.

public interface IDbUtilityProviderFactory 
{
    IDbConnectionStringBuilder CreateConnectionStringBuilder();
    IDbParameter CreateParameter();
}

public interface IDbBlockingProviderFactory : IDbUtilityProviderFactory 
{
    IDbBlockingCommand CreateBlockingCommand();
    IDbBlockingConnection CreateBlockingConnection();
}

public interface IDbAyncProviderFactory : IDbUtilityProviderFactory 
{
    IDbCommandAsync CreateAsyncCommand();
    IDbConnectionAsync CreateAsyncConnection();
}

@abatishchev

Orang-orang di balik gagasan CoreClr (kerangka kerja mengkilap baru) memiliki pola pikir yang sama sekali berbeda dari orang-orang di balik implementasinya (kompatibilitas mundur dengan basis kode berusia 15 tahun adalah raja).

Terima kasih telah memperjelas ini, sepertinya perlu ditunjukkan. Secara umum saya percaya tim MS sangat peduli dengan kompatibilitas mundur yang sangat penting untuk mengembangkan bahasa dan platform mereka. Hanya saja keputusan seputar System.Data tidak dibuat dengan mempertimbangkan ekosistem yang lebih luas - yang harus dilayani oleh abstraksi inti ini secara setara.

  • Dengan menghapus antarmuka, Anda memperburuk keadaan.
  • Tidak ada yang usang sampai dihiasi dengan [Usang]. Dan tidak masalah siapa yang memikirkan apa pada suatu saat. Ini kontrak dan jika Anda tidak memuaskannya maka Anda tidak.

Dengan tepat.

Mengenai versi antarmuka. Perbaiki saya jika saya salah tetapi saya pikir inti CoreClr lebih berbutir halus, versi independen? Menghancurkan perubahan? Ledakan! Versi utama baru dirilis.
Sepertinya setelah 15 tahun pengalaman desain, Anda akan mengulangi kesalahan yang sama tetapi sekarang memiliki paket nuget versi independen dan dirilis. Argumen di atas identik dengan kerangka monolitik lama yang baik, meskipun tidak lagi.
Jika kompatibilitas mundur adalah suatu keharusan daripada Anda tidak dapat menghapus antarmuka tersebut. Jika tidak maka mari kita berhenti membicarakannya dan mendesain API dari awal, kali ini mendengarkan penulis ORM utama dan pengembang berpengalaman ADO.NET lainnya.
Terima kasih.

@abatishchev poin yang sangat bagus. Saya sendiri juga bertanya-tanya: apa sebenarnya gunanya argumen kompatibilitas mundur? Jika fitur baru ditambahkan ke CoreClr, semua yang menggunakannya tidak akan berjalan di .net penuh, jadi untuk amannya hanya bisa menggunakan sikap biasa. (yang tidak pernah bekerja dengan baik).

Maaf untuk kesunyian yang lama di pihak saya.

Porting ke .NET Core

Pertama, mari kita bicara tentang gajah di dalam ruangan, yaitu bahwa .NET Core hampir tidak memiliki banyak API yang tersedia seperti yang diharapkan banyak orang -- termasuk kami --.

Saya bekerja dengan tim saya untuk mengumpulkan satu set dokumen tentang bagaimana kita akan mendekati area porting aset yang ada ke .NET Core.

Kami berencana untuk memindahkan lebih banyak fungsi yang saat ini hanya ada di .NET Framework / Mono ke .NET Core. Dokumen ini akan menjelaskan bagaimana kami akan melakukannya, bagaimana kami memprioritaskan, dan seperti apa mekanismenya. Saya tidak hanya ingin pekerjaan itu terjadi di tempat terbuka, saya juga ingin mengaktifkan komunitas untuk membantu kami mem-porting lebih banyak fungsionalitas.

Melanggar Perubahan

Ada satu area yang menyebabkan banyak kebingungan ketika orang berbicara tentang .NET Core. Izinkan saya mengklarifikasi satu hal:

Ini bukan perubahan besar jika .NET Core memiliki lebih sedikit API daripada .NET Framework.

Alasannya karena .NET Core adalah platform baru dan secara teknis dapat memiliki serangkaian API yang berubah-ubah. Namun, tentu saja, kami tidak menginginkan pengaturan yang sewenang-wenang -- itulah yang kami lakukan di masa lalu. Tujuan .NET Core adalah untuk memiliki cerita di mana orang-orang dapat membuat perpustakaan (dan dengan aplikasi konsol hingga aplikasi tertentu) yang akan berjalan di .NET Framework dan .NET Core. Ini mengharuskan ada subset dari kedua platform yang 100% kompatibel. Dalam konteks itu, Anda akan mendengar kami berbicara tentang melanggar perubahan.

Selain itu, maksud kami adalah memiliki bilah kompatibilitas yang tinggi di dalam .NET Core. Dengan kata lain, kami tidak berencana melakukan perubahan pemutusan API antara satu versi .NET Core API dan versi lainnya.

Antarmuka

Menambahkan anggota ke antarmuka -- menurut definisi -- merupakan perubahan besar. Beberapa orang berpendapat bahwa dampaknya rendah dan ada cara untuk memodelkannya, tetapi sampai sekarang ini adalah perubahan biner dan pemecah sumber.

WinRT, yang didasarkan pada COM dan dengan demikian sangat bergantung pada antarmuka, memecahkan masalah ini dengan membuat lebih banyak antarmuka, seperti IFoo , IFoo2 , IFoo3 . Ini bisa dilakukan, tetapi tentu saja berantakan tanpa fitur runtime atau bahasa untuk membuatnya tertahankan. Sejauh ini, fitur seperti itu tidak ada. Namun, sebagai anggota tim desain bahasa, saya cukup tertarik untuk mendengar proposal. Bahasa dan platform lain memiliki ide terkait di ruang itu, dan saya juga secara aktif mencari opsi (seperti campuran/sifat, semua ekstensi Swift, atau anggota default untuk antarmuka).

Karena kami masih peduli dengan kompatibilitas mundur, kami biasanya lebih menyukai tipe dasar abstrak daripada antarmuka.

Antarmuka ADO.NET

Semua itu dikatakan, mari kita bicara tentang pertanyaan asli di utas ini: mengekspos antarmuka penyedia ADO.NET.

Seperti yang dijelaskan David: kami menganggap ini usang ketika tipe dasar abstrak diperkenalkan, yang ada di .NET 2 / Visual Studio 2005. Tampaknya ada kepercayaan kuat bahwa memiliki antarmuka ini sangat penting untuk mem-port kerangka kerja ORM ke .NET Core. Bagi saya, ini memberikan bukti yang cukup bahwa kita harus port antarmuka ke .NET Core.

Namun, seperti halnya dengan semua API baru, kita perlu memperhatikan salah satu tujuan utama .NET Core, yaitu memiliki tumpukan komponen. Antarmuka IDataReader memiliki ketergantungan pada DataTable , yang memiliki ketergantungan pada DataSet . Sebagaimana diuraikan dalam dotnet/runtime#14302, kami tidak menentang penambahan dukungan untuk DataTable tetapi kami menganggap DataSet warisan. Namun, kami mungkin masih menambahkannya sebagai paket terpisah, tetapi bagaimanapun ini akan memerlukan pemutusan rantai ketergantungan dari antarmuka -> DataTable -> DataSet . Saya akan bekerja sama dengan @YoungGah untuk melihat apa yang bisa kami lakukan di sana.

Apakah pendekatan ini akan mengatasi masalah tersebut?

Kecuali saya salah, satu-satunya ketergantungan DataTable di IDataReader adalah
GetSchemaTable() metode, sudah dibahas panjang lebar di DataTable
rantai. Saya dengan mudah mengakui, bagaimanapun, bahwa fakta bahwa ada
berharap untuk menambahkan _some_ mind dengan fungsi serupa di kemudian hari (apakah
melalui DataTable atau tidak) membuatnya sangat canggung untuk mengekspos ini di
antarmuka, karena memperluas antarmuka nanti bermasalah. Itu tidak akan terjadi
cukup sederhana seperti "hapus metode untuk saat ini, tambahkan yang lain nanti"
Pada 5 Des 2015 12:17, "Immo Landwerth" [email protected] menulis:

Maaf untuk kesunyian yang lama di pihak saya.
Porting ke .NET Core

Pertama, mari kita bicara tentang gajah di dalam ruangan, yaitu .NET
Core hampir tidak memiliki banyak API yang tersedia seperti kebanyakan orang -- termasuk
kami -- akan berharap untuk.

Saya bekerja dengan tim saya untuk mengumpulkan satu set dokumen tentang bagaimana kita akan pergi
untuk mendekati area porting aset yang ada ke .NET Core.

Kami berencana untuk memindahkan lebih banyak fungsi yang saat ini hanya
ada di .NET Framework / Mono hingga .NET Core. Dokumen ini akan memanggil
bagaimana kami akan melakukannya, bagaimana kami memprioritaskan, dan apa yang akan dilakukan oleh mekanik
menjadi. Saya tidak hanya ingin pekerjaan itu terjadi di tempat terbuka, saya juga ingin
aktifkan komunitas bantu kami port lebih banyak fungsi.
Melanggar Perubahan

Ada satu area yang menyebabkan banyak kebingungan ketika orang membicarakannya
.NET Inti. Izinkan saya mengklarifikasi satu hal:

Ini bukan perubahan besar jika .NET Core memiliki lebih sedikit API daripada .NET
Kerangka.

Alasannya karena .NET Core adalah platform baru dan secara teknis dapat
memiliki serangkaian API yang berubah-ubah. Namun, tentu saja, kami tidak ingin
set sewenang-wenang
http://blogs.msdn.com/b/dotnet/archive/2014/12/04/introducing-net-core.aspx
-- itulah yang kami lakukan di masa lalu. Tujuan dari .NET Core adalah untuk memiliki
cerita di mana orang dapat menulis perpustakaan (dan dengan aplikasi konsol untuk tertentu
memperpanjang bahkan aplikasi) yang akan berjalan di .NET Framework dan .NET Core. Ini
mensyaratkan bahwa ada subset dari kedua platform yang merupakan 100%
kompatibel. Dalam konteks itu, Anda akan mendengar kami berbicara tentang melanggar perubahan.

Selain itu, maksud kami adalah memiliki bilah kompatibilitas yang tinggi di dalam .NET Core.
Dengan kata lain, kami tidak berencana melakukan perubahan pemutusan API antara
satu versi dari .NET Core API dan lainnya.
Antarmuka

Menambahkan anggota ke antarmuka -- menurut definisi -- merupakan perubahan besar.
Beberapa orang berpendapat bahwa dampaknya rendah dan ada cara untuk membuat model
itu, tapi seperti berdiri sampai hari ini adalah biner dan perubahan sumber melanggar.

WinRT, yang didasarkan pada COM dan dengan demikian sangat bergantung pada antarmuka,
memecahkan masalah ini dengan membuat lebih banyak antarmuka, seperti IFoo, IFoo2,
IFoo3. Itu bisa dilakukan, tapi pasti berantakan tanpa runtime atau
fitur bahasa untuk membuatnya tertahankan. Sejauh ini, fitur seperti itu tidak ada.
Namun, sebagai anggota tim desain bahasa, saya cukup tertarik untuk
mendengar proposal. Bahasa dan platform lain memiliki ide terkait dalam hal itu
ruang, dan saya juga secara aktif mencari opsi (seperti
campuran/sifat, ekstensi Swift-semuanya, atau anggota default untuk
antarmuka).

Karena kami masih peduli dengan kompatibilitas mundur, kami biasanya menyukai
tipe dasar abstrak melalui antarmuka.
Antarmuka ADO.NET

Semua itu dikatakan, mari kita bicara tentang pertanyaan asli di utas ini:
mengekspos antarmuka penyedia ADO.NET.

Seperti yang dijelaskan David: kami menganggap ini sudah usang ketika basis abstrak
jenis diperkenalkan, yang ada di .NET 2 / Visual Studio 2005. Tampaknya
bahwa ada kepercayaan kuat bahwa memiliki antarmuka ini sangat penting untuk
port kerangka kerja ORM ke .NET Core. Bagi saya, ini memberikan bukti yang cukup
bahwa kita harus port antarmuka ke .NET Core.

Namun, seperti halnya dengan semua API baru, kita perlu memperhatikan salah satu dari
tujuan utama .NET Core, yang memiliki tumpukan komponen. NS
antarmuka IDataReader memiliki ketergantungan pada DataTable, yang memiliki:
ketergantungan pada DataSet. Sebagaimana diuraikan dalam dotnet/runtime#14302
https://github.com/dotnet/corefx/issues/1039 , kami tidak menentang untuk menambahkan
dukungan untuk DataTable, tetapi kami benar-benar tidak ingin mem-port DataSet. Jadi
menambahkan antarmuka akan membutuhkan pemutusan ketergantungan itu. Saya akan bekerja dengan
dengan @YoungGah https://github.com/YoungGah untuk melihat apa yang bisa kami lakukan di sana.

Apakah pendekatan ini akan mengatasi masalah tersebut?


Balas email ini secara langsung atau lihat di GitHub
https://github.com/dotnet/corefx/issues/3480#issuecomment -162115855.

Ya, IDataReader memiliki ketergantungan pada DataTable yang memiliki ketergantungan pada DataSet.

Seperti disebutkan sebelumnya, kami tidak dapat menghapus anggota dari antarmuka, jadi kami perlu memutuskan ketergantungan itu dengan cara lain; baik dengan tidak mem-porting antarmuka, atau dengan memutus dependensi DataTable -> DataSet.

Apakah pendekatan ini akan mengatasi masalah tersebut?

Ya, memulihkan Antarmuka ADO.NET bahkan tanpa metode GetSchemaTable() akan menyelesaikan ketergantungan berat pada masalah antarmuka ADO.NET yang saat ini saya hadapi.

Saya berasumsi melanggar DataTable -> ketergantungan DataSet jika itu berarti GetSchemaTable() juga akan disertakan, akan menjadi pendekatan yang lebih disukai bagi mereka yang bergantung pada GetSchemaTable() (jadi itu akan menjadi pilihan saya) - tetapi Saya akan memberikan bobot lebih kepada para pengembang yang terpengaruh ini.

@terrajobst terima kasih atas ringkasan Anda dan berbagi pertimbangan Anda.

@terrajobst terima kasih atas ringkasan dan penjelasannya. Saya memelihara Npgsql jadi saya menulis dari perspektif penyedia ADO.NET, bukan ORM.

Di .NET Core, Microsoft tampaknya memiliki keinginan untuk menghapus beberapa fitur lama ADO.NET, yaitu DataTable/DataSet dan antarmuka. Ini menciptakan API yang lebih baik dan lebih bersih, tetapi menciptakan pekerjaan yang substansial bagi pengguna yang sudah bergantung pada antarmuka dan API DataTable/DataSet.

Saya pribadi berpikir bahwa membunuh DataTable/DataSet adalah hal yang baik, dan bahwa API metadata yang baru dan lebih baik harus diperkenalkan (saya pikir ini benar bahkan tanpa mematikan DataTable/DataSet). Saya tidak meminimalkan
rasa sakit yang disebabkan oleh kerusakan ini pada konsumen ORM (dan lainnya), tetapi satu hal yang perlu diingat adalah jika ada kesempatan untuk membersihkan dan memperkenalkan kerusakan - .NET Core adalah kesempatan itu.

Faktor frustasi tambahan di sini adalah bahwa menjaga antarmuka ADO.NET juga berarti menjaga DataTable/DataSet juga. Dengan kata lain, meskipun saya pribadi tidak terlalu merasakan masalah antarmuka, menjaganya berarti menyimpan DataTable/DataSet dan itu tampaknya lebih bermasalah.

Karena saya tidak tahu berapa banyak ORM di luar sana yang masih bergantung pada antarmuka, dan saya juga tidak tahu seberapa besar upaya yang akan mereka lakukan untuk transisi ke kelas dasar, pilihannya tidak terlalu jelas di sini. Tapi firasat saya adalah untuk mengambil kesempatan ini dan membersihkan semuanya bahkan jika itu berarti beberapa orang menderita...

PS Apa pun yang Anda lakukan, jangan ikuti rute ledakan antarmuka, yaitu IFoo2, IFoo3. Itu hanya non-solusi.
PPS Jika Anda memutuskan untuk membuat API metadata non-DataTable baru di .NET Core dan ingin pustaka .NET Core berjalan di .NET Framework, ini berarti Anda harus merilis .NET Framework baru dengan API baru bersama dengan .NET Inti.

@terrajobst Terima kasih telah memecah keheningan ;). Saya pikir masalah intinya adalah tidak ada desain untuk ADO.NET. Belum ada untuk beberapa waktu dan itu menunjukkan di berbagai bagian API yang merupakan gado-gado fitur empuk tanpa memikirkan semuanya selama lebih dari beberapa menit (tampaknya). Saya setuju dengan @roji dalam hal ini: .NET core adalah kesempatan sekali seumur hidup untuk melakukan sesuatu tentang berbagai hal sehingga .NET core tidak boleh ditahan oleh aturan (menurut saya, konyol) bahwa itu harus kompatibel dengan .NET penuh.

Yang mengatakan, jika hal-hal tidak akan berubah menjadi lebih baik untuk ADO.NET (yaitu mendapat desain nyata di mana API umum dirancang yang kemudian khusus di SqlClient dan bukan sebaliknya! Jadi fitur yang tersedia tidak di SQL Server tetapi di Basis Data lain ditambahkan ke API umum dan tidak diserahkan ke penulis penyedia ADO.NET), maka hal terbaik berikutnya adalah mem-porting sebanyak mungkin, termasuk antarmuka dan kami sendiri devs pihak ke-3 #ifdef di sekitar lubang yang akan ditinggalkan.

Ketergantungan DataTable dapat menjadi masalah, karena antarmuka IDataReader akan menyulitkan untuk menjaga agar semuanya tetap kompatibel dengan .NET full _if_ datatable dalam bentuk apa pun yang tidak di-porting. Tapi saya pikir itu adalah tujuan yang sia-sia. Dikatakan oleh MS beberapa kali bahwa .NET full tidak akan menerima pembaruan sebanyak / sesering inti .NET, jadi jika sesuatu _baru_ ditambahkan ke inti .NET, tidak ada yang dapat menggunakannya, karena menggunakannya membuat perpustakaan segera tidak kompatibel dengan .NET penuh. Saya mungkin melewatkan sesuatu di sini, jadi jika itu masalahnya, tolong perbaiki saya :)

Itu saja membuatnya menjadi situasi yang aneh: harus ada kompatibilitas ke belakang, tetapi dalam praktiknya ini tampaknya sulit untuk dicapai dan bagaimanapun juga. IMHO jika itu ditangani terlebih dahulu, hasilnya dapat digunakan untuk membuat keputusan yang tepat tentang apa yang harus dilakukan dengan API inti .NET, yaitu meningkatkannya alih-alih menyeret cruft lama yang dirancang dengan buruk dari .NET penuh. Itu tidak berarti semua API dirancang dengan buruk, namun dengan ADO.NET (seperti yang saya jelaskan di posting sebelumnya), banyak hal yang belum dilakukan dengan benar selama bertahun-tahun. Membuat terobosan yang bersih dan sebagai gantinya menerapkan sistem yang bisa lebih kuat (JDBC masih berjalan kuat, ODBC masih berfungsi seperti yang dilakukan 25 tahun yang lalu) dan adaptif terhadap perubahan lebih disukai.

Memikirkan lebih banyak tentang ini, komentar @FransBouma tentang persyaratan kompatibilitas mundur sangat masuk akal. Salah satu janji .NET Core adalah iterasi yang lebih cepat berkat kemasan Nuget yang dikomponenkan - alih-alih pembaruan .NET Framework datang sekali/dua kali setahun, pembaruan .NET Core dapat dirilis kapan pun diperlukan. Tampaknya nilai ini sangat terbatas jika pembaruan tidak pernah dapat merusak kompatibilitas dengan .NET Framework...?

Saya mengerti bahwa kompatibilitas mundur adalah persyaratan yang melampaui diskusi khusus ADO.NET ini, saya hanya ingin tahu.

Ini sebaliknya @roji : iterasi pendek diaktifkan dengan tidak merusak API.

Jika Anda seorang pengembang .Net dan bangunan Anda terus rusak setiap minggu karena API kerangka kerja yang mendasarinya terus berubah, maka tidak akan lama sebelum Anda mulai mempertimbangkan platform lain.

Jadi iterasi cepat didorong oleh perubahan yang tidak melanggar.

(diedit)
Anda hanya dapat mengulangi tanpa merusak perubahan sampai Anda harus misalnya menambahkan sesuatu ke antarmuka kelas, perubahan perilaku (!) Atau penambahan perilaku, yang bukan merupakan perubahan yang melanggar dalam arti harfiah (perubahan perilaku juga demikian), tetapi menggunakannya pada .net core akan membuat kode Anda tidak kompatibel dengan .net full, jadi dalam hal ini akan membuat .net core tidak kompatibel lagi dengan .net full _untuk potongan kode_ itu. IMHO mana yang turun ke .NET core selalu akan memiliki antarmuka dan perilaku (kelas) yang sama seperti pada .NET full, hingga byte terakhir (yang IMHO tidak berkelanjutan) atau akan mendapatkan fitur baru yang di-backport nanti (yang secara harfiah adalah apa MS mengatakan btw) ke .NET full, secara efektif membuatnya tidak kompatibel. Itu tergantung pada sisi pagar mana Anda tentu saja: jika Anda mengatakan: 'ada satu set umum (kelas) antarmuka X dengan perilaku yang ditentukan B, dan keduanya .NET core dan .NET mengimplementasikannya secara penuh dan X & B akan' t berubah di masa depan', itu masih berarti ada kerangka kerja baru di luar X & B yang akan mendapatkan hal-hal baru dan tepatnya di mana hal-hal dapat berubah dan juga di mana masa depan berada.

Orang bisa melangkah jauh dengan ini, misalnya antarmuka / kelas yang digunakan di X & B di .net core sebenarnya membungkus kelas / antarmuka baru di .NET core. Terserah pengembang yang menggunakannya untuk menggunakan X & B atau yang baru dengan desain yang lebih baik dan tanpa API yang sama dengan .NET full.

Karena kita sudah harus #ifdef cara mengatasi hal-hal yang hilang di X & B, ketika mendukung kedua kerangka kerja, IMHO lebih baik untuk hanya dapat menargetkan antarmuka/kelas baru di inti .NET karena cepat atau lambat perubahan perilaku (bahkan mungkin sangat halus , seperti pengecualian yang berbeda dalam situasi tertentu) akan tetap muncul di sana, jadi kode 'porting' ke .NET core dengan _new_ API (bukan X&B) akan lebih baik. Kami tetap harus port, setidaknya begitulah yang saya lihat.

@ryanbnl , saya setuju dengan @FransBouma. Intinya bukan kita ingin bisa memecahkan API. Itu membatasi .NET Core untuk dapat dijalankan dalam .NET Framework berarti Anda tidak akan pernah dapat menambahkan apa pun ke antarmuka .NET Core apa pun, atau menambahkan anggota abstrak ke kelas dasar abstrak apa pun. Kedua perubahan ini tidak benar-benar merusak kompatibilitas mundur dalam arti sebenarnya bagi seseorang yang menggunakan .NET Core, keduanya merusak kompatibilitas dengan .NET Framework.

@roji kecuali yang eksternal baru dari paket kerangka kerja (misalnya bukan GAC) ketika dapat kompatibel dengan Kerangka dan inti dan berjalan pada iramanya sendiri; tapi itu mungkin lebih banyak perubahan untuk penyedia ORM dan nama System.Data.IDbConnection sudah diambil...

@benaadams itu komentar yang valid - Saya hanya memikirkan API kerangka kerja non-nuget seperti ADO.NET. Namun, ini tampaknya mencakup ruang API yang cukup untuk menjadi perhatian - .NET Core tidak akan dapat mengembangkan semua ini (baca: tambahkan metode antarmuka atau metode abstrak) tanpa menjadi tidak dapat dijalankan

Saya tidak yakin apa yang Anda maksud tentang IDbConnection meskipun ...

@roji hanya berarti paket baru yang menyediakan jenis ini misalnya System.Data.Database ; agar tetap kompatibel dengan inti dan penuh, tidak dapat mendefinisikan ulang jenis apa pun yang akan menjadi kerangka kerja penuh GAC atau akan berbenturan.

Pada titik nuget; itu ada alasan mengapa ini tidak bisa hidup di nuget untuk penuh dan inti; dan menghentikan pos api System.Data 4.6.1+?

Itu akan menyebabkan rasa sakit yang lebih besar sekarang; tetapi beberapa compat sudah rusak, di mana itu menjatuhkan antarmuka, atau hanya menjatuhkan DataSet sehingga beberapa pengerjaan ulang sudah perlu dilakukan untuk coreclr oleh penyedia ORM.

Api yang sama sekali baru yang hidup di nuget dan di luar kerangka kerja GAC ​​dapat kompatibel ke belakang untuk digunakan dengan netstandard1.2 misalnya 4.5.2+, coreclr, UWP, mono/Xamarin dll. Meskipun itu akan lebih menyakitkan sekarang - tetapi itu mungkin waktu yang lebih baik daripada nanti.

Mengingat bahwa API baru sedang digunakan untuk achema dan semacamnya, menunjukkan DataSet tidak akan datang (atau DataTable ), haruskah ini ditutup? Kedengarannya seperti kelas dasar adalah jalan ke depan berdasarkan komentar di dotnet/corefx#5609 dan jenis penerusan, yang berarti antarmuka tidak ada gunanya diberikan GetSchemaTable() dan beberapa lainnya tidak ada di sana untuk membawanya untuk compat ... apakah itu adil untuk dikatakan?

Apa yang harus ditutup? Jika kita tidak dapat memiliki GetSchemaTable() karena ketergantungan DataTable/DataSet itu satu hal, tetapi antarmuka masih harus dipulihkan (tanpa GetSchema jika diperlukan) dan memudahkan porting basis kode yang ada dengan ketergantungan yang mendalam pada mereka. Antarmuka yang hilang adalah pemblokir, saya masih menunggu rilis dengan mereka sebelum kami dapat memulai pekerjaan untuk mendukung dnx/core.

Saya setuju dengan @mythz , antarmuka adalah subjek lain dan sangat penting. Mungkin tidak untuk sebagian besar pengguna, tetapi pengguna yang sama ini menggunakan kode yang ditulis oleh sekelompok kecil dan kode itu _is_ mengandalkan antarmuka ini (serta fitur ADO.NET penting lainnya yang hilang seperti DbProviderFactory).

Sejujurnya, dengan dorongan ekstrim menuju label 'RTM', saya memiliki sedikit harapan kita akan mendapatkan API yang solid dengan 1.0. Ini akan seperti .NET 2.0 lagi: semua kesalahan yang dibuat oleh versi pertama kemudian akan diperbaiki.

@FransBouma

Menambahkan antarmuka ke .NET Core akan menjadi perubahan tambahan. Jadi bahkan jika itu tidak cocok untuk V1, itu bisa ditambahkan dalam versi apa pun setelahnya, bahkan 1.1.

semua kesalahan yang dibuat oleh versi pertama kemudian akan diperbaiki.

Jangan tersinggung, tapi begitulah cara kerja perangkat lunak.

@terrajobst

Jadi bahkan jika itu tidak cocok untuk V1, itu bisa ditambahkan dalam versi apa pun setelahnya, bahkan 1.1.

ya, bukan karena secara teknis tidak mungkin, itu karena hasil dari melakukannya (atau kurangnya melakukannya) memiliki konsekuensi (jangkauan jauh), di mana Microsoft bukan yang menderita, itu kita. Sejauh ini saya telah melihat sedikit sikap apatis untuk itu. Semuanya keren dan mengasyikkan untuk bekerja pada kerangka kerja baru, tetapi tidak dikembangkan di ruang yang bersih untuk audiens baru. Ini juga tidak berarti tidak ada sejarah untuk dipelajari, sebaliknya.

Jangan tersinggung, tapi begitulah cara kerja perangkat lunak.

Lihat, ini persis apa yang saya maksud di atas: Anda bukan orang yang harus berurusan dengan konsekuensi dari keputusan Anda, saya harus. Dan saya sudah berurusan dengan konsekuensi dari keputusan serupa oleh para pendahulu Anda, jadi saya memberi tahu Anda agar Anda tidak membuat kesalahan yang sama.

Saya tahu cara kerja perangkat lunak, saya telah menjadi pengembang perangkat lunak profesional sekarang selama lebih dari 21 tahun. Saya memberikan saran jujur ​​saya, bukan sebagai pemula tetapi sebagai ahli yang tangguh dalam pertempuran di bidang khusus ini. Anda dapat melakukan apa yang Anda inginkan dengannya, hanya saja saya harap Anda berpikir dua kali sebelum membuat keputusan ringan di sini, karena konsekuensinya jauh, dan seperti yang saya katakan: kita harus berurusan dengan ini, bukan Anda.

Bahkan kesalahan bisa diperbaiki nanti, tetapi itu belum dilakukan, itu alasan yang baik untuk tidak melakukannya sejak awal, bukan?

Kalian bereaksi berlebihan. Saya ragu efek ini akan memiliki konsekuensi yang sama seperti .NET lama.

Dengan coreclr yang dibundel dalam setiap aplikasi, warisan memiliki arti yang sangat berbeda. Seperti hampir tidak ada yang peduli jika fitur dari asp.net mvc 5 tidak di-backport ke mvc 4 atau 3. Legacy di sini akan memiliki arti yang berbeda, dan ada sejarah di proyek lain yang menunjukkan hal itu.

Untung @terrajobst terbuka untuk mempertimbangkan ini untuk versi berikutnya.

@nvivo Tolong jangan mencoba untuk meremehkan konsekuensi yang harus dihadapi _I_, karena Anda tidak harus menghadapinya, tetapi saya melakukannya.

Terima kasih @FransBouma telah menempatkan saya di tempat saya. Adalah kesalahan saya untuk berpikir saya bisa mengomentari masalah ini. Anda tentu lebih mumpuni dari saya untuk mengetahui hal-hal apa saja yang mempengaruhi pekerjaan saya.

Faktanya, meskipun saya membuka masalah itu, itu sama sekali tidak berpengaruh pada pekerjaan saya atau hal-hal yang saya pedulikan. Saya hanya berpikir tentang pengembang miskin seperti Anda yang melakukan semua kerja keras di planet ini.

Saya sangat senang orang-orang seperti Anda ada di sini untuk menangani masalah yang sulit. Harap jangan ragu untuk memberi tahu kami lagi dan lagi dan lagi (dan lagi) betapa banyak masalah yang lebih penting yang harus Anda tangani.

Terima kasih @FransBouma.

_sigh_ Di mana saya mengatakan semua itu? Yang saya katakan adalah tolong jangan meremehkan sesuatu, karena Anda melakukannya dengan 'Anda bereaksi berlebihan', saya tidak berpikir saya bereaksi berlebihan. Dengan 'Anda tidak harus berurusan dengan mereka' maksud saya: konsekuensi untuk _me_. Karena saya tahu apa yang saya bereaksi seperti yang saya lakukan. Rupanya itu 'berlebihan'.

Tapi apa pun.

Kami memiliki jawaban untuk masalah ini di sini dan di sini .

Jawaban resminya adalah: Antarmuka tidak akan ada di .NET Core 1.0, dan meskipun tidak mungkin, mereka dapat dipertimbangkan untuk rilis mendatang dalam beberapa bentuk yang berbeda dari apa yang ada di .NET.

Saya menutup masalah ini karena pertanyaan awal telah ditangani.

@nvivo Terima kasih, tetapi sebaiknya tinggalkan tanggapan resmi apa pun kepada orang-orang yang benar-benar bertanggung jawab atas proyek yang juga mampu menutup masalah sendiri setelah mereka memutuskan bahwa itu telah diselesaikan.

@terrajobst Apakah ada tanggapan/garis waktu resmi yang diperbarui untuk Antarmuka? dan apa cara terbaik untuk melacak item pekerjaan ini ke depan? haruskah kami membuka edisi baru atau akankah Anda terus memberikan pembaruan apa pun di sini?

Mari kita biarkan ini terbuka untuk saat ini. Cara saya melihatnya, jawabannya bukan "jangan buka antarmuka". Jawabannya adalah "mari kita temukan cara untuk mengeksposnya tetapi mari kita pikirkan apa artinya bagi ketergantungan DataTable".

Maaf untuk kembali kepada kalian begitu terlambat. Setelah mendiskusikan berbagai opsi dalam tim kami, kami memutuskan untuk mengembalikan antarmuka dengan kelas DataTable yang kosong. Ini bukan solusi ideal, tetapi mengingat kerangka waktu RTM, pendekatan ini akan memastikan kami dapat mengejar opsi yang layak seputar DataTable/DataSet di masa mendatang. Kami akan mencoba menghadirkan antarmuka untuk System.Data.Common oleh v1 RTM; SqlClient tidak akan mengimplementasikan antarmuka oleh v1. Terima kasih atas tanggapan dan kesabaran Anda. Umpan balik Anda adalah bagian penting untuk membuat tumpukan data menjadi produk yang layak.

@YoungGah terima kasih atas pembaruannya, jika kelas DataTable hanya akan menjadi penampung kosong, apa yang membutuhkan begitu banyak waktu/usaha (yaitu menahannya) agar tidak diterapkan oleh SqlClient v1?

@mythz Biayanya adalah dalam mengimplementasikan antarmuka dalam tipe dasar / meneruskannya ke metode yang ada. Biayanya harus minimal, tetapi biasanya hal-hal muncul :senyum:

Kami telah menambahkan antarmuka berikut ke .Net CoreFX di System.Data.Common

ParameterIData
Koleksi IDataParameter
Pembaca Data
IDataRecord
IDbPerintah
Koneksi IDb
IDbDataParameter
IDbTransaksi

Ini dilakukan di PR https://github.com/dotnet/corefx/pull/6359

@saurabh500 Barang bagus, thx!

:+1:

:+1:

Luar biasa; apakah ada tonggak untuk ini untuk memukul nuget? rc3?

Pada 25 Februari 2016 pukul 02:54, Saurabh Singh [email protected]
menulis:

Kami telah menambahkan antarmuka berikut ke .Net CoreFX di System.Data.Common

ParameterIData
Koleksi IDataParameter
Pembaca Data
IDataRecord
IDbPerintah
Koneksi IDb
IDbDataParameter
IDbTransaksi

Ini dilakukan di PR dotnet/corefx#6359 https://github.com/dotnet/corefx/pull/6359


Balas email ini secara langsung atau lihat di GitHub
https://github.com/dotnet/corefx/issues/3480#issuecomment -188577701.

Salam,

Marc

Seperti yang dikomentari di PR, kita perlu memahami mengapa tidak ada metode asinkron pada antarmuka ini. Seperti yang diusulkan, ini pada dasarnya adalah versi antarmuka ADO.NET 1.1 yang dipangkas, dan saya tidak berpikir idenya seharusnya hanya kompatibilitas dengan kode lama.

Antarmuka harus fokus pada status ado.net saat ini, karena metode asinkron harus menjadi cara default untuk mengakses basis data apa pun saat ini. Tanpa dukungan nyata untuk metode async, antarmuka ini tidak berguna untuk pengembangan modern
perkembangan.

Dan bahkan termasuk metode async dari .NET 4.5, beberapa metode tambahan, seperti DbTrabsaction.CommitAsync harus ditambahkan juga.

Penyedia postgres menambahkan beberapa metode tambahan seperti CommitAsync ke api mereka yang cukup berguna dan perlu.

Antarmuka saat ini baik-baik saja seperti apa adanya. Implikasi dari mengubahnya terlalu besar.

Model async sangat berbeda dari yang sinkron dan seperti yang mungkin Anda ketahui, jika Anda menggunakan model async, Anda harus melakukannya sepenuhnya. Oleh karena itu, tidak ada alasan untuk memiliki antarmuka yang sama untuk kedua API. Buat yang baru untuk async API.

Jika tim .NET ingin menyediakan API yang lebih modern, mengapa tidak membuat API baru yang tidak disebut ADO.NET? Tidak ada warisan yang bisa dihalangi dan tidak ada keluhan dari masyarakat. Itu juga cocok dengan bagaimana dnx akan didistribusikan? yaitu, paket independen.

:+1: pada antarmuka, kompromi yang bagus.

Saya tidak berpikir idenya seharusnya hanya kompatibilitas dengan kode lama.

Itulah ide _seluruh_ di sini. Jika tidak, kelas dasar akan baik-baik saja. Itu banyak sekali rasa sakit porting yang ingin kita hindari.

Tanpa dukungan nyata untuk metode async, antarmuka ini tidak berguna untuk pengembangan modern.

Saya tidak setuju dengan ini, tetapi saya tidak setuju dengan versi async dari antarmuka (yang tidak ada yang mengimplementasikannya hari ini). Ini akan menjadi fitur baru. Kami tidak dapat secara surut menambahkan anggota ke antarmuka yang ada, yang hanya merusak terlalu banyak hal. Memiliki IDbReaderAsync atau sesuatu bukanlah IMO yang gila, tetapi ini adalah diskusi yang berbeda.

Saya sangat percaya metode async harus _tidak_ berada di kelas dasar, jika implementasi default adalah pembungkus sinkronisasi - itu secara aktif buruk dan boros. Jika ada proposal lain, biarlah, tetapi sekali lagi: itu harus menjadi masalah yang berbeda.

Ok, mungkin saya mengekspresikan diri saya dengan cara yang salah di sini atau terlalu kuat dengan kata-kata saya.

Saya mendukung antarmuka tambahan untuk async jika diperlukan. Apa yang saya tidak setuju adalah memiliki sesuatu yang mendefinisikan kontrak resmi untuk ADO.NET (itulah antarmuka) tetapi tidak memiliki metode async di mana pun di dalamnya.

Tapi kemudian, memiliki antarmuka alternatif untuk metode async mungkin akan menyebabkan masalah lain...

Saya sangat percaya metode async tidak boleh berada di kelas dasar, jika implementasi default adalah pembungkus sinkronisasi - itu secara aktif buruk dan boros.

Saya setuju, ini adalah alasan utama mengapa sebagian besar penyedia tidak repot-repot menerapkan api async yang sebenarnya. Tetapi mengubahnya akan merusak lebih banyak kode dan mungkin menyebabkan lebih banyak gangguan daripada menghapus antarmuka, karena kelas dasar telah menjadi API sebenarnya untuk penyedia sejak 2.0.

Memutakhirkan perpustakaan untuk tidak menggunakan antarmuka 1.1 akan menyebabkan dampak yang hampir nol dibandingkan dengan menghapus semua kode asinkron yang ditulis dalam beberapa tahun terakhir, yang akan menjadi bencana. Kompromi adalah memiliki keduanya. Kode apa pun yang ditulis hari ini harus menggunakan api async, jadi mengabaikannya tidak masuk akal.

Kode apa pun yang ditulis hari ini harus menggunakan API async.

Saya tidak ingin melukai terlalu keras, tetapi dunia ideal itu sangat jauh dari kenyataan. Async sangat meresap dan menular. Anda tidak bisa hanya mengandalkan API async di perpustakaan dan mengharapkan seluruh aplikasi menjadi konsumen asinkron (mengubah _ton_ kode mereka menjadi asinkron juga) secara tiba-tiba. Sinkronisasi -> Asinkron di mana-mana juga sangat buruk karena banyak alasan kebuntuan dan efisiensi. Akan ada kode sinkron yang ditulis selama bertahun-tahun yang akan datang.

Ada kebutuhan yang kuat untuk kedua API. Intinya adalah: jangan hapus yang saat ini atau tunda kehadirannya untuk set baru yang hipotetis dan belum dirancang. Kita bisa khawatir tentang set kedua/baru secara mandiri.

Memutakhirkan perpustakaan untuk tidak menggunakan antarmuka 1.1 apa pun akan menyebabkan dampak yang hampir nol dibandingkan dengan menghapus semua kode asinkron yang ditulis dalam beberapa tahun terakhir

Untuk apa yang Anda maksud? Tidak ada API async untuk kode seperti itu. Jika Anda mengandalkan API semacam itu, mereka tidak berada di kelas dasar atau antarmuka, tetapi pada penyedia secara langsung. Itu tidak akan terpengaruh oleh ini.

Kode apa pun yang ditulis hari ini harus menggunakan api async, jadi mengabaikannya tidak masuk akal.

Meninggalkan banyak hal tidak masuk akal...kecuali kenyataan bahwa kita semua dibatasi oleh sumber daya (terutama waktu). Saya tidak percaya ada yang meninggalkan sesuatu _permanently_. Tidak ada yang keluar dari meja. Itu hanya belum sampai. Saya akan membuka masalah lain khusus untuk memulai spesifikasi pada antarmuka async untuk generasi mendatang.

Untuk apa yang Anda maksud? Tidak ada API async untuk kode seperti itu. Jika Anda mengandalkan API semacam itu, mereka tidak berada di kelas dasar atau antarmuka, tetapi pada penyedia secara langsung. Itu tidak akan terpengaruh oleh ini.

.NET 4.5 memperkenalkan metode async pada kelas dasar penyedia. Ini terjadi pada tahun 2012, hampir 4 tahun yang lalu, jadi telah menjadi bagian dari API penyedia ADO.NET untuk sementara waktu. Entity Framework 6 (dirilis pada 2013) bergantung pada API asinkron ini untuk semua penyedia.

Metode async sudah menjadi bagian dari ADO.NET untuk waktu yang cukup lama sehingga banyak orang akan berteriak jika itu tidak termasuk dalam .NET Core. Saya memiliki _legacy code_ yang menggunakan metode async di ADO.NET.

Saya menganjurkan bahwa karena mereka _sudah_ bagian dari ADO.NET, ini juga harus ada di API antarmuka baru.

Jika orang ingin (dan seharusnya) menggunakan API async, mereka sudah dapat melakukannya
bahwa _sebelum perubahan ini_ dengan menggunakan tipe dasar. Pada akhirnya, permintaan
untuk mendukung antarmuka dibuat untuk alasan kompatibilitas mundur;
menambahkan metode ke antarmuka _benar-benar membuat ini keluar dari air_.
Yang mengatakan, itu sebenarnya hampir mungkin sebagai _metode ekstensi_ dan
tipe-memeriksa terhadap tipe dasar abstrak, tapi ... cukup jelek dan tidak
sepadan dengan rasa sakitnya IMO.

Jadi; versi singkat: Saya pribadi tidak dapat menambahkan async ke
antarmuka, karena itu menghancurkan satu hal yang kami inginkan pada awalnya
tempat. Jika Anda ingin async: Anda perlu membuat kode terhadap kelas dasar, atau gunakan
alat yang menutupi detail ini untuk Anda.

Saya menganjurkan bahwa karena mereka sudah menjadi bagian dari ADO.NET, ini juga harus ada di API antarmuka baru.

Anda benar-benar salah memahami tujuan dari Antarmuka ADO.NET ini yaitu untuk menjaga kompatibilitas dengan kode yang ada. Ini bukan antarmuka _baru_, ini adalah antarmuka _yang ada_. Jika Anda ingin mengakses API yang lebih baru, referensikan tipe dasar beton.

@nvivo Maaf, saya hanya tidak mengikuti Anda - saya sedang berbicara tentang _interface_ API - itu tidak pernah ada. Tipe dasar sudah memiliki semua metode *Async yang sama - apakah ada sesuatu yang spesifik yang hilang? Saya pikir Anda berpendapat bahwa mereka harus digabungkan ke dalam antarmuka ... ya tentu saja, tapi itu masalah lain yang saya anjurkan untuk Anda buka.

Saya lebih suka mereka telah menjadi antarmuka sejak awal karena implementasi dasar yang diperlukan untuk membuat pendekatan saat ini berfungsi (async over sync) adalah pengorbanan yang mengerikan untuk membuat seluruh pendekatan berfungsi. Namun, kami juga tidak dapat memiliki keduanya: apakah mereka pindah ke antarmuka atau mereka hadir (seperti kasus saat ini) untuk meminimalkan jeda.

Ya, saya pikir kita akan berputar-putar di sini. Saya menyatakan ini sebelumnya, saya tidak berpikir antarmuka harus ditambahkan _just_ untuk membantu kode porting. Dari sudut pandang kompatibilitas, kelas dasar telah menjadi API resmi untuk ADO.NET sejak tahun 2005, dan itulah yang diterapkan oleh penyedia. Apa pun yang menggunakan IDbCommand atau IDbConnection dapat dengan mudah di-porting (dan seharusnya di-porting) untuk menggunakan kelas dasar dengan pencarian/penggantian dan tidak memiliki kerugian.

Saya tahu Anda bukan penggemar ifdef, tetapi mendukung ini untuk platform baru hanya akan menjadi bagian dari migrasi.

Saya setuju ini seharusnya menjadi antarmuka selama ini, tetapi karena tidak, saya ingin melihat masalah ini tidak terulang. Jika antarmuka ditambahkan, setidaknya mereka harus mewakili API saat ini, dan bukan seperti satu dekade yang lalu. Metode async adalah bagian integral dari API saat ini dan ke arah itulah Microsoft bergerak selama beberapa waktu. Itu masih akan menjadi sumber yang kompatibel, hanya lebih lengkap.

@mgravell

Jika orang ingin (dan seharusnya) menggunakan API async, mereka sudah dapat melakukannya _sebelum perubahan ini_ dengan menggunakan tipe dasar.

Ini bukan tentang mampu melakukan apapun. Ini tentang arsitektur. Antarmuka adalah kontrak, .NET Core adalah kerangka kerja baru yang menambahkan kontrak ini ke versi API yang didesain ulang.

Inti .NET tidak boleh menambahkan kontrak resmi ke API baru hanya untuk membantu memigrasikan kode yang sangat lama, sementara sebagian besar hal lainnya akan tetap hilang. Jika itu menjadi perhatian, orang-orang tidak cukup mencari alasan mengapa mereka perlu mengubah kode mereka.

Jika hanya itu yang dilakukan tim, maka tidak apa-apa .. itu hanya pilihan yang buruk IMO.

Apa pun yang menggunakan IDbCommand atau IDbConnection dapat dengan mudah di-porting (dan seharusnya di-porting) untuk menggunakan kelas dasar dengan pencarian/penggantian dan tidak memiliki kerugian.

Palsu. Masalah telah dibahas berkali-kali di utas ini dari beberapa penulis perpustakaan dengan pengalaman tangan pertama yang terpengaruh oleh ini.

Saya tahu Anda bukan penggemar ifdefs

Solusi apa pun yang mengharuskan pelanggan akhir untuk menggunakan ifdefs adalah pengalaman pengembang yang rusak dan bukan pemula, yaitu tidak akan pernah ada produk sukses yang mengharuskan pelanggan mengotori kode mereka dengan #defs ketika ada alternatif.

Jika antarmuka ditambahkan, setidaknya harus mewakili API saat ini

Ini bukan antarmuka baru, itu antarmuka yang dipulihkan. API saat ini dan yang akan datang adalah kelas dasar, bukan antarmuka ini. Seharusnya tidak ada masalah di sini, Anda dapat melupakan antarmuka ini dan terus menggunakan tipe dasar seperti sebelum antarmuka ini dipulihkan.

Tidak ada nilai baru yang ditambahkan ke utas ini lagi. Antarmuka ADO.NET yang ada telah dipulihkan sehingga utas ini dapat diistirahatkan. Satu-satunya hal yang diperlukan dari utas ini adalah pembaruan ke DataTable dan GetSchemaTable() karena berkaitan dengan antarmuka yang ada. Jika Anda ingin mengusulkan perubahan arsitektur atau menganjurkan antarmuka baru, buka edisi baru - yang akan menghentikan semua orang dalam daftar ini dari spam.

@mythz mari kita setuju untuk tidak setuju.

Hanya menambahkan 2 sen saya sebagai pengembang ORM lain, kelas abstrak selalu berbau kode saat tidak didukung oleh antarmuka. Akan senang melihat antarmuka baru yang disediakan untuk mencocokkan kelas abstrak dan tanda tangan metode yang kelebihan beban dengan API antarmuka persyaratan minimum.

Acungan jempol untuk komunitas yang angkat bicara.

kelas abstrak selalu berbau kode saat tidak didukung oleh antarmuka

@psibernetic Bisakah Anda membantu saya memahami pernyataan itu? Bagaimana dengan ini adalah bau kode?

@psibernetic

Antarmuka dan kelas abstrak memberi kita kontrak, keduanya memberi kita abstraksi dan definisi yang baik untuk API. Antarmuka paling berguna ketika mengimplementasikan kelas yang dapat mengimplementasikan lebih dari satu antarmuka atau merupakan subkelas dari kelas dasar lain (dengan asumsi itu adalah keuntungan yang sangat besar dari kelas dasar itu). Dalam kasus ini khususnya, kelas konkret untuk Koneksi, Perintah, dan seterusnya untuk penyedia tertentu memiliki hubungan IS A yang kuat dengan definisi API abstrak. Saya benar-benar tidak dapat membayangkan skenario ketika beberapa pengembang perlu menambahkan implementasi konkret untuk IDbConnection atau IConnection ke subkelas. Skenario hampir satu-satunya adalah kelas baru yang hanya diturunkan untuk kelas abstrak dan untuk "menduplikasi" definisi yang sama pada Antarmuka lebih berfungsi (tidak perlu) untuk perancang API.

Apakah Anda melihat keuntungan atau skenario spesifik dan konkret untuk memiliki dua abstraksi yang sama? Kapan antarmuka memberikan manfaat praktis dan nyata _melebihi_ kelas abstrak dalam desain API khusus ini?

Satu-satunya keuntungan yang dapat saya pikirkan untuk Antarmuka adalah kompatibilitas mundur yang kita perlukan dengan yang lama untuk memecahkan kode yang berjalan kurang aktual tergantung pada antarmuka tersebut. Jika kita tidak memiliki antarmuka lama, saya cukup yakin bahwa kelas abstrak sudah cukup.

@eocampo Anda benar bahwa kelas abstrak mungkin menyediakan abstraksi dan kontrak yang "cukup baik". Saya selalu mencoba untuk menyediakan antarmuka yang sangat sempit yang mewakili tindakan yang dapat diambil seperti IAsyncCommand dan sejenisnya. Itu memungkinkan kerangka kerja saya untuk dicolokkan dengan cara yang mungkin belum dipertimbangkan pada waktu desain kerangka kerja dengan sedikit kemungkinan NotSupportedExceptions atau NotImplementedExceptions yang mengerikan.

@davkean Bau kode adalah bahwa dalam banyak kasus, meskipun tidak semua, Anda memerlukan pelaksana untuk mengimplementasikan atau mewarisi seluruh rangkaian fungsionalitas dasar yang mungkin tidak relevan. Saya ingat pernah melihat implementasi IDataReader yang membaca dari cache atau di memori. Tidak yakin apakah kelas abstrak DbDataReader akan mengizinkannya, tetapi namanya menyiratkan tidak.

Model praktik terbaik yang diikuti terutama di dot net telah mengekspos antarmuka dan mewarisi dari kelas dasar bukan?

Model praktik terbaik yang diikuti terutama di dot net telah mengekspos antarmuka dan mewarisi dari kelas dasar bukan?

@psibernetic Yah tidak selalu. Misalnya rekomendasi ini di situs MSDN memiliki lebih dari satu dekade di sana. Dan pedoman itu sangat umum dari .Net Framework 2.0 setidaknya.

Juga ini adalah referensi yang baik dari pedoman untuk desain perpustakaan di .Net dari hari-hari awal:

http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613

Pokoknya saya pikir diskusi yang sulit di sini adalah tentang dua mata pelajaran sekarang:

a) Antarmuka hanya untuk kompatibilitas mundur atau dapatkah kita "mulai dari awal" (memecahkan kode) untuk memungkinkan antarmuka dan desain API yang lebih bersih.
b) Berapa banyak yang bisa kita dapatkan untuk desain modern dan bersih dengan biaya tidak kompatibel dengan kerangka .Net penuh. (Kompatibilitas khususnya antara .Net Core dan Full core pada akses data [bukan kompatibilitas tingkat paling rendah dan wajib])

Dari sudut pandang saya, jika kita memiliki kelas dasar abstrak sebagai kontrak utama dan pilihan, maka _interfaces_ harus cocok dengan yang lama hanya untuk kompatibilitas. Saya mengerti bahwa @nvivo telah menyatakan bahwa setelah .Net 2.0 kontrak resmi adalah kelas dasar abstrak sehingga kami _bisa_ berpikir bahwa antarmuka tidak akan menyelesaikan masalah kompatibilitas tetapi @mythz dan @mikeobrien juga telah menyediakan data keras di sini tentang ketergantungan penyedia pada antarmuka 1.1.

Untuk berhenti mengirim spam dan mendiskusikan topik di sini, kita perlu membaca kembali percakapan panjang ini dan saya tidak tahu apakah kita dapat menyetujui DAFTAR topik tertentu yang kita bahas atau apakah ide yang baik untuk membuat dua atau tiga topik baru. masalah untuk setiap topik tertentu. Saya lebih dari saran pertama karena ada banyak poin bagus di sini. Saya tidak punya ide bagus tentang bagaimana kita dapat meringkas ulang semua ini dan menghapus beberapa kebisingan (bahkan milik saya).

Berbicara tentang antarmuka, apakah ada rencana untuk membuat bagian dari System.Data menjadi generik? Itu selalu mengganggu saya bahwa System.Data tidak pernah benar-benar memperbarui API di luar .NET 1.1, membuat orang harus menggunakan peretasan seperti metode ekstensi .AsEnumerable() untuk mendapatkan IEnumerablekeluar dari DataTable. Mengapa koleksi seperti DataRowCollection belum dimutakhirkan untuk mengimplementasikan antarmuka generik ketika semua hal lain dalam kerangka kerja dilakukan ketika 2.0 keluar?

Apakah akan ada rintisan System.Data dengan jenis pengalihan di dalamnya? Saya perlu menggunakan ODP.NET tetapi sekarang saya tidak bisa.

Membuat dotnet/corefx#7874

@mgravell @ploeh "

Saya bukan ahli Haskell, tetapi pemahaman saya adalah mereka akan memungkinkan Anda untuk memasang IDbConnection , IDbConnectionAsync , dan antarmuka bersama apa pun di masa mendatang setelah fakta tanpa merusak sumber atau kompatibilitas biner, dan tanpa memaksa penyedia pihak ketiga untuk mengimplementasikan semuanya. Ini, sambil mempertahankan mockability mudah.

Apakah ini pemahaman yang benar? Jika demikian, apakah ada kemungkinan fitur ini akan hadir di .NET secara nyata?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat