Runtime: Machen Sie Schnittstellen als die offizielle ADO.NET-Provider-API anstelle von Klassen

Erstellt am 26. Sept. 2015  ·  174Kommentare  ·  Quelle: dotnet/runtime

Von dem, was ich derzeit auf der corefx-progress-Seite für System.Data.Common sehen kann , wurden die Schnittstellen (IDbCommand, IDbConnection usw.) zugunsten der Verwendung abstrakter Klassen entfernt.

Aber in der neuen API sind die meisten Hauptmethoden weder virtuell noch abstrakt. Allein auf DbCommand können wir dies sehen:

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();

Obwohl diese Methoden sicherlich virtuell oder abstrakt gemacht werden können, wäre es viel nützlicher, die echten Schnittstellen zurück zu haben und jede öffentliche API von diesen Schnittstellen abhängig zu machen, anstatt von den abstrakten Klassen.

Dies ist vor allem beim Entwickeln von Bibliotheken nützlich. Heutzutage ist es sehr schwierig, einen Datenleser zu verspotten, damit er zu Testzwecken einen bestimmten Wert zurückgibt. Das gleiche gilt, um sicherzustellen, dass ExecuteReaderAsync aufgerufen wurde, nicht ExecuteReader usw.

Ich schlage vor, stattdessen sollte die Provider-Factory als Schnittstelle gemacht werden:

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

Und dann folgen Sie von dort dem Rest des Anbieters zu Dingen wie IDbDataReader , IDbTransaction usw.

Wir wissen, dass die Schnittstellen in der Vergangenheit aus irgendeinem Grund nicht mehr synchron waren und die abstrakten Klassen zur offiziellen API wurden, aber das muss in corefx nicht mehr der Fall sein.

Beachten Sie, dass dies nicht bedeutet, System.Data.Common in irgendeiner Weise zu entfernen, sondern stattdessen die Common-Klassen dazu zu bringen, diese Schnittstellen zu implementieren, und Sie würden System.Data.Common nicht verwenden, es sei denn, Sie implementieren den Anbieter. Anwendungen würden stattdessen nur von den Schnittstellen abhängen.

Bitte beachten Sie dies, um die API auf corefx 1.0 besser testbar zu machen.

Bezieht sich auf Diskussionen zu dotnet/runtime#14302 und dotnet/runtime#15269.

area-System.Data

Hilfreichster Kommentar

Wir können keine Mitglieder zu Schnittstellen hinzufügen

Richtig, und das ist eine _gute_ Eigenschaft von Schnittstellen. Die Bevorzugung abstrakter Basisklassen ist der sicherste Weg, die API-Entropie voranzutreiben, anstatt sie zu bekämpfen.

Obwohl Sie die Prinzipien von OOD nicht _müssen_ , würde ich vorschlagen, dass Sie dies tun, wenn Sie OO-APIs erstellen. Kurz gesagt, das Interface Segregation Principle (ISP) besagt, dass _kein Client gezwungen werden sollte, von Methoden abhängig zu sein, die er nicht verwendet_.

Wenn Sie einer vorhandenen Abstraktion neue Methoden hinzufügen, verstoßen Sie automatisch gegen den ISP.

Sie können entscheiden, dass Sie sich nicht an SOLID halten müssen, weil Sie Microsoft sind und mit der BCL arbeiten Gegenargumente).

Nachdem ich seit 6-7 Jahren einige Open-Source-Projekte betreut habe, ist es meiner Erfahrung nach besser, die Schnittstellen klein zu halten. Wenn Sie einer Abstraktion neue Funktionen hinzufügen müssen, führen Sie eine neue Schnittstelle ein.

Alle 174 Kommentare

Sie wären auf abstrakte Basisklassen umgestiegen, da Schnittstellen nicht versioniert werden können.

Ich vermute, dass die nicht virtuellen Methoden eine andere virtuelle Methode aufrufen. Virtuelle Methoden beeinträchtigen die Leistung, sodass Sie die Dinge nicht unnötig virtuell machen möchten.

@JamesNK Ich

@NickCraver , @roji , @FransBouma da ihr anscheinend Interesse an der ADO.NET API habt, habt ihr etwas dazu zu sagen?

@YoungGah ,

Ich vermute, dass die nicht virtuellen Methoden eine andere virtuelle Methode aufrufen. Virtuelle Methoden beeinträchtigen die Leistung, sodass Sie die Dinge nicht unnötig virtuell machen möchten.

Beim Ausführen einer Abfrage in einer entfernten Datenbank und beim Verarbeiten der Ergebnisse sind die bei einem virtcall verlorenen Nanosekunden vernachlässigbar. Außerdem verwendet ADO.NET dieses System von Anfang an (ebenso viele andere APIs in .NET) und niemand hat sich darüber beschwert, dass ihr DB-Code aufgrund virtueller Methodenaufrufe so langsam ist;)

Ich kann asynchrone Methoden in Ihrer Liste sehen, daher vermute ich, dass MS vor ein paar Jahren nicht asynchron zu IDbCommand hinzufügen konnte. Wer weiß, was morgen bringt, das neue Methoden oder Eigenschaften erfordert.

Schnittstellen nicht versionieren.

Leistung ist nur ein Grund, etwas nicht virtuell zu machen. Reduzieren Sie die Oberfläche für Implementierungen vielleicht? Ich werde jemand bei MS sagen lassen, warum er sich dagegen entschieden hat, ich weiß nicht viel über ADO.NET, also würde ich nur spekulieren.

@JamesNK Ich denke, Ihre Bedenken sind

  1. ADO.NET ist seit .NET 2.0 ziemlich stabil, was ein Jahrzehnt lang war - obwohl die asynchrone API später hinzugefügt wurde, änderte sie das Verhalten der API nicht, sondern fügte nur asynchrone Gegenstücke hinzu - ich sehe keine großen Änderungen in das Datenbanktreiber-Paradigma in Kürze
  2. CoreFx soll eine andere Versionierungsidee haben, da man für alte Apps einfach die bisherige CLR beibehalten kann. Probleme bei der Schnittstellenversionierung sollten hier also keine so großen Auswirkungen haben

Bedenken Sie auch, dass selbst ein SQL-Server auf "localhost" einige ms aufwenden wird, nur um eine Verbindung herzustellen und eine leere Abfrage zurückzugeben. In der Praxis dauern die meisten _schnellen_ Abfragen an relationale Datenbanken ~20 ms.

Die Möglichkeit, die API mit Standardtools wie NSubstitute oder Moq zu simulieren, ist für Entwickler heute viel wertvoller, als Mikrosekunden bei der Suche nach virtuellen Methoden zu sparen.

Ich glaube, ich habe hier keine sehr starke Meinung, aber hier sind einige Anmerkungen:

  • Stimmen Sie den obigen Ausführungen zu, dass das Entfernen von virtuellen vs. nicht virtuellen in einer API für den Datenbankzugriff vernachlässigbar ist.
  • Basisklassen ermöglichen es ADO.NET, Implementierungen bereitzustellen. Ich vermute, darum geht es CommandBehavior.Default den meisten nicht virtuellen, nicht abstrakten Methoden - die Überladung von ExecuteReader, die kein CommandBehavior akzeptiert, übergibt
  • Ich bin mir nicht sicher, ob dies für alle wichtigen Mocking-Frameworks gültig ist, aber zumindest in Moq ist es nicht genauso einfach, eine Basisklasse zu verspotten wie eine Schnittstelle?

Insgesamt scheint die Idee, entweder die Basisklassen oder die Schnittstellen zu löschen, also gut (einfacher). Da ich keinen Vorteil von Schnittstellen sehe (es sei denn, ich liege falsch bezüglich der Leichtigkeit des Verspottens) und Basisklassen können allgemeine Funktionen bereitstellen (dh die nicht virtuellen, nicht abstrakten Methoden), ich denke, Microsofts Ansatz, die Schnittstellen zu dumpen scheint mir gut zu sein...

Ich stimme @roji in all seinen Punkten zu.

@roji nur eine Anmerkung, ich schlage nicht vor, die Basisklassen zu löschen, ich schlage vor, die Schnittstellen als Standard-API hinzuzufügen. Basisklassen können weiterhin Standardverhalten implementieren.

Beim Testen hatte ich große Probleme beim Testen, ob meine API die richtigen Methoden aufruft. Um zu überprüfen, ob ExecuteDataReader beispielsweise die richtigen Parameter erhalten hat, müssen Sie eine andere geschützte Methode überprüfen, die intern mit anderen Parametern aufgerufen wird. Das ist alles andere als ideal.

Wenn ich mich nicht irre, ist derzeit das einzige Framework, das die ADO.NET-API verspotten kann, das MS Fakes-Framework, das absolut alles verspotten kann, indem es Anrufe abfängt. Moq und andere können das nicht.

Mich würde interessieren, ob andere ähnliche Probleme hatten.

@roji nur eine Anmerkung, ich schlage nicht vor, die Basisklassen zu löschen, ich schlage vor, die Schnittstellen als Standard-API hinzuzufügen. Basisklassen können weiterhin Standardverhalten implementieren.

Entschuldigung, das habe ich falsch verstanden. Behält Ihr Vorschlag in diesem Fall nicht mehr oder weniger die Dinge bei, wie sie in .NET sind (nicht, dass daran etwas falsch wäre)?

Beim Testen hatte ich große Probleme beim Testen, ob meine API die richtigen Methoden aufruft. Um zu überprüfen, ob ExecuteDataReader beispielsweise die richtigen Parameter erhalten hat, müssen Sie eine andere geschützte Methode überprüfen, die intern mit anderen Parametern aufgerufen wird. Das ist alles andere als ideal.

Wenn ich Ihr Szenario verstehe (nicht sicher), ist Moqs CallBase für diese Art von Szenario nützlich - Standardimplementierungen werden von der Basisklasse geerbt

@roji

Behält Ihr Vorschlag nicht mehr oder weniger die Dinge bei, wie sie in .NET sind (nicht, dass daran etwas falsch wäre)?

Nicht genau. Die Schnittstellen-API wurde in .NET 1.0 hinzugefügt und in 2.0 veraltet. Seit 2.0 sind die Schnittstellen aus Kompatibilitätsgründen da, aber es gibt keine Schnittstelle für ProviderFactory oder andere Klassen in Data.Common. Es gibt auch nichts für die async-API oder 2.0 oder neuere Methoden.

Moq kann nur Dinge verspotten, die verspottet werden können. Es muss eine virtuelle oder abstrakte Methode geben, die überschrieben werden kann, oder eine geschützte Methode, die aufgerufen werden kann. Die aktuelle API bietet für einige Fälle eine Methode, für die meisten jedoch nicht. Es gibt viele Dinge, die intern, privat und unerreichbar sind, es sei denn, Sie verwenden Reflexion. Nur MS Fakes kann dies tun, da es die Referenz durch ein Shim ersetzt, aber dies ist nur auf VS Enterprise verfügbar und für Open-Source-Projekte nutzlos.

Es hört sich so an, als hätte ich einen sehr speziellen Fall, aber sicherlich war jeder, der jemals versucht hat, diese API zu verspotten, mit diesem Problem konfrontiert. Google einfach, fast jede Lösung endet mit "Mock the Legacy Interface API or build a wrapper you can spot":

@nvivo OK, danke für die zusätzlichen Details - ich gebe zu, dass ich mit dem Verspotten von ADO.NET nicht sehr weit gekommen bin.

Was ich nicht verstehe, ist, warum Sie interne, private und anderweitig unerreichbare Methoden einer API verspotten möchten. Sollten Sie nicht öffentliche Methoden verspotten, die direkt für Ihren eigenen Anwendungscode verfügbar sind (was Sie zu testen versuchen)? Ich sehe das Problem mit den nicht-virtuellen Methoden (zB der 0-Parameter ExecuteReader() Überladung), aber da diese in ADO.NET immer (?) eine virtuelle Überladung aufrufen (zB ExecuteReader(CommandBehavior)), gibt es a echtes Problem hier?

Können Sie nur ein einfaches Beispiel geben, um Ihr Problemszenario zu verstehen?

@nvivo Wir haben derzeit keine Pläne, Schnittstellen angesprochen wurde . Ein gutes Beispiel für das Zurückbleiben von Schnittstellen ist das Hinzufügen von asynchronen und Streamingmethoden in .NET Framework 4.5. Als wir diese neuen Funktionen hinzugefügt haben, haben wir uns sorgfältig mit der Erweiterung der Schnittstellen befasst. Die Optionen, die wir damals hatten, waren entweder die Bereitstellung von InterfaceFooV2 oder separate Schnittstellen für asyn und Streaming. Wir wollten InterfaceFooV2 nicht hinzufügen, da wir absehen können, dass wir in Zukunft weitere APIs hinzufügen möchten. Das Hinzufügen separater Schnittstellen für jede neue Funktionalität wäre verwirrend, da sie nicht an die vorhandenen Schnittstellen gebunden sind.

@roji Ich hatte Fälle, in denen ich sicherstellen möchte, dass eine bestimmte Überladung von ExecuteReader aufgerufen wurde und nicht "eine der Überladungen". Es ist die Art von Dingen, die Sie nur in Bibliotheken haben, nicht im Benutzercode.

@YoungGah danke für die Info. Ich schließe das dann.

Haben die Verantwortlichen für diese Veränderung eine Vorstellung von ihren Auswirkungen? Die Kernschnittstellen von ADO.NET gibt es seit über einem Jahrzehnt und der Datenzugriff ist das Zentrum der meisten Geschäftsanwendungen. Ich kann mir nicht vorstellen, dass es nicht die höchste Priorität ist, so viele vorhandene Codebasen nicht absichtlich zu durchbrechen? Dies sind einige der kritischsten High-Level-Schnittstellen in .NET, das Entfernen dieser bricht jede ADO .NET-Datenzugriffsbibliothek auf dem Markt und folglich jedes Projekt, das sie verwendet. Sie zu entfernen führt zu einer künstlichen Fragmentierung, die zu Frustration und Verwirrung führt, die die Einführung von CoreCLR behindern.

Sie können Schnittstellen weiterhin versionieren und quellkompatibel machen, indem Sie einfach Erweiterungsmethoden für alle neuen APIs von IDbCommand hinzufügen, z.

public interface IDbCommand
{
    //...
}

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

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

Die IDbCommand Kernschnittstelle muss sich nach der Veröffentlichung von DNX nie ändern und Sie können mit der obigen Strategie weiterhin Funktionen hinzufügen. Sie können diese Erweiterungen auch später (in einer größeren Breaking-Version) aufrollen und in die Kernschnittstelle einbinden. In jedem Fall erhalten wir die stabilen ADO.NET-Kernschnittstellen, die für die Migration vorhandener Codebasen und folglich für die Einführung von CoreCLR entscheidend sind.

Ich wurde von @davkean gebeten , konkrete Beispiele dafür bereitzustellen, welche Auswirkungen das Entfernen von ADO .NET- Kernschnittstellen haben wird. Ich kann mir nicht vorstellen, dass diese Änderung in Betracht gezogen wurde, ohne die unermesslichen Auswirkungen zu bewerten, die sie auf das vorhandene .NET-Ökosystem haben würde, aber andererseits wurde sie auch durchgeführt, sodass es möglich ist, dass sie nicht in Betracht gezogen wurde - was ich hier annehmen werde - darin war es nicht.

Trotz der Rolle von EF als Standard-ORM von .NET und seines herausragenden Erfolgs bei der Eroberung eines Großteils des Marktanteils gibt es immer noch eine große Anzahl von .NET-Entwicklern, die aus verschiedenen Gründen stattdessen alternative ORMs bevorzugen. Ein wichtiges Merkmal in Bezug auf CoreCLR ist beispielsweise, dass sie erstklassige Unterstützung für Mono/Linux/OSX sowie die Unterstützung mehrerer alternativer RDBMS bieten. Da CoreCLR stark auf den Linux/OSX-Entwicklermarkt drängt, ist es umso besser, je mehr Unterstützung für Alt-RDBMs vorhanden ist. Ein weiteres wichtiges Merkmal der Entwickler, die Micro ORMs einsetzen, ist, dass sie außerhalb der MS-Ökosystem-Standards evaluiert haben, um das für sie am besten geeignete ORM auszuwählen. Nach allem, was ich gesehen habe, gibt es eine hohe Korrelation zwischen aktiven .NET OSS (dh Anti-Dark Matter)-Entwicklern und Entwicklern, die Micro ORMs einsetzen, ebenso erwarte ich eine hohe Korrelation mit frühen Anwendern von CoreCLR – deren Hauptnutzenversprechen ist unter OSX/Linux entwickeln. Dies sind einige der Gründe, warum es von Vorteil wäre, das umgebende .NET-Ökosystem in Ihre Entscheidungsfindung einzubeziehen, wenn Sie grundlegende Designentscheidungen wie diese treffen.

Alternative ORM-Downloads

Ein flüchtiger Blick auf NuGet-Downloads gibt einen Hinweis darauf, wie der Nicht-EF-Marktanteil aussieht:

NRuhezustand - 1M+
Elegant - 1M+
OrmLite - 500k+
Einfache.Daten - 300k+
PetaPoco - ~100k
NPoco - 30k+

Die reellen Zahlen sind viel mehr als das, da viele Micro ORMs wie Dapper, Massive, PetaPoco, NPoco usw. so konzipiert wurden, dass sie in eine einzige Drop-In-.cs-Datei passen, sodass NuGet nicht über ihre wahre Verwendung berichtet. Es gibt auch Closed-Source-ORMs wie LLBLGen Pro, die eine große Benutzerbasis haben, aber ihre Verwendung wird nicht von NuGet gemeldet.

Auswirkungen auf alternative ORMs

Dank GitHub können wir schnell suchen, um zu sehen, wie viele verschiedene Quelldateien den Kern enthalten
IDbConnection , IDbCommand und IDataReader ADO .NET-Schnittstellen, die von dieser Änderung betroffen sind:

IDbVerbindungIDbBefehlIDataReader
NHibernate59181132
Elegant172117
OrmLite1795426
Einfache.Daten29276
NPoco4103

Hinweis: Diese Ergebnisse zeigen nur Quelldateien, die tatsächliche Anzahl der fehlerhaften Referenzen ist viel höher.

Auswirkungen auf den Quellcode des Kunden

Die tatsächlichen Auswirkungen dieser Änderung erstrecken sich auch auf alle Projektabhängigkeiten, die diese ORMs verwenden.
Leider ist der Effekt nicht auf interne Implementierungen beschränkt, da er auch den Kunden kaputt macht
Quellcode, da viele Micro ORMs nur Erweiterungsmethoden über ADO.NET-Schnittstellen sind, damit der Client
Code sieht so aus:

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"));

Ein Erweiterbarkeitsmerkmal bei der Verwendung von Erweiterungsmethoden besteht darin, dass diese ORMs "offen" sind und Kunden ORMs mit ihren eigenen erstklassigen APIs erweitern können, indem sie Erweiterungsmethoden in ihren eigenen Projekten hinzufügen - diese sind ebenfalls defekt.

Offensichtlich ist jetzt auch jeder Quellcode, der IDbConnection weitergibt, für die Arbeit mit CoreCLR verboten.

ZB werden die Kern-ADO.NET-Schnittstellen in High-Level-Frameworks wie ServiceStack stark verwendet , da es die minimale Abhängigkeit ist, um Multi-RDBMS-Datenzugriff zu ermöglichen. Es wurde auch angenommen, dass es sich bei allen Klassen, die sich wahrscheinlich nicht ändern würden, um die Kernschnittstellen von ADO.NET handelt.

Zusammenfassung

Ich bin persönlich erstaunt, dass es in .NET jemals eine Zukunft ohne diese Schnittstellen geben würde.
Schnittstellen sind vom Design her zweckspezifisch, um mehrere Implementierungen zu ermöglichen, und ADO.NET ist eine davon
der wichtigsten "offenen Anbietermodelle" in .NET. Ich habe keine Ahnung, welche Prioritäten dazu geführt haben, dass diese Schnittstellen entfernt wurden, aber sowohl den massiven vorhandenen .NET-Codebasen, die auf diesen Schnittstellen basieren, als auch dem alternativen EF-.NET-Ökosystem sollte eine viel höhere Priorität eingeräumt werden. Dies führt zu erheblichen Unterbrechungen und stellt eine wesentliche Barriere dar, die für die Unterstützung bestehender .NET 4.x- und CoreCLR-Plattformen erforderlich ist.

Die derzeitige Wahrnehmung ist, dass ADO.NET/CoreCLR neu gestaltet wird, um erstklassige Unterstützung für EF und SQL Server zu bieten, wobei der Rest des Ökosystems außer Acht gelassen wird – undurchsichtige Entscheidungen wie diese verstärken nur dieses Stereotyp .

Als früheres Mitglied des .NET-Teams (ich arbeite jetzt an Roslyn) war ich zusammen mit den SQL- und Entity-Framework-Teams stark am ursprünglichen Design der neuen Data Commons beteiligt. Ich bin im Moment nicht daran beteiligt, aber ich kann einige Hintergrundinformationen hinzufügen, um einige der Aussagen zu korrigieren, die ich auf Twitter und höher sehe.

Das aktuelle Design von System.Data.Common für .NET Core begann im Dezember 2012, ungefähr 2 Jahre vor der Open Source.

Ziele:

  • Entwerfen eine moderne Oberfläche für die .NET - Core, dass reduzierte Doppel Konzepte ( IDbConnection vs DbConnection ), Verwirrungen, Irrtümer und Schichtung Fragen (split SqlClient von DataCommon, spalteten DataSet aus Kern Abstraktionen) aus das ursprüngliche Design von .NET 1.0. Eine, die sowohl von bestehenden Verbrauchern als auch von _neuen_ Entwicklern von .NET Framework leicht aufgenommen werden würde.
  • Ermöglichen Sie Anbietern und Verbrauchern, eine einzelne Binärdatei/Quelle für .NET Core zu erstellen und dann dieselbe Binärdatei in .NET Framework auszuführen. Beachten Sie, dass das Gegenteil kein Ziel war; in der Lage zu sein, .NET Framework Binär-/Quellcode zu verwenden und ohne einige Änderungen auf .NET Core auszuführen.

Korrektur einiger Dinge, die verbreitet werden:

  • Die Schnittstellen sind in ihrer jetzigen Form nicht versionierbar. Wir können Schnittstellen keine Member hinzufügen, und der obige Vorschlag von @mythz über Erweiterungsmethoden erfordert, dass Provider sowieso von den abstrakten Basisklassen abgeleitet werden.
  • System.Data.Common hat sich _nicht_ vom Anbietermodell entfernt. Die Schnittstellen wurden entfernt, da es sich um ein älteres .NET 1.0-Konzept handelte, das durch die in .NET 2.0 eingeführten abstrakten Basisklassen ersetzt/dupliziert wurde. Als wir diese Entscheidung trafen, leitete sich jeder Anbieter, den wir finden konnten, von den Basisklassen ab.
  • Wie die Schnittstellen sind auch die Basisklassen nachahmbar.
  • Uns war klar, dass für diejenigen, die die .NET 1.0-Schnittstellen verwenden, einige Änderungen erforderlich sind, es ist jedoch eine sehr einfache Portierung, um zu den Basisklassen zu wechseln. Sehen Sie sich beispielsweise diese wenigen Änderungszeilen für AutoMapper an: (https://github.com/AutoMapper/AutoMapper.Data/blob/master/AutoMapper.Data/DataReaderMapper.cs#L14).

Etwas, das ich nicht verstehen kann:

Wir können keine Mitglieder zu Schnittstellen hinzufügen

Warum ist es nicht in Ordnung, CoreCLR-Schnittstellen noch Mitglieder hinzuzufügen, es ist in Ordnung, sie vollständig herauszureißen?

der obige Vorschlag von @mythz über Erweiterungsmethoden erfordert, dass Anbieter sowieso von den abstrakten Basisklassen abgeleitet werden.

Der wichtige Teil ist, dass die Schnittstellen vorhanden sind und Quellcode, der sie referenziert, kompilieren können.

Wenn Sie die Schnittstellen nicht versionieren möchten, entfernen Sie sie mit EOL, stellen Sie einfach die Schnittstellen wieder her, wie sie waren, bevor sie herausgerissen wurden, und verringern Sie die Belastung, die jetzt jeder anderen Bibliothek auferlegt wird, die sie verwendet. Ich meine, diese Kernschnittstellen wurden nie ohne Warnung oder Migrationspfad veraltet. Aber wir werden dafür bestraft, dass wir eine veröffentlichte, bekannte, stabile API als integralen Bestandteil unserer Bibliotheken übernehmen?

Es ist eine sehr einfache Portierung, um zu den Basisklassen zu wechseln.

Dies muss jeder Quelldatei hinzugefügt werden, die auf die ADO.NET-Schnittstellen verweist, und zwingt Kunden, ihren Code mit benutzerdefinierten Buildsymbolen zu überfrachten.

Es scheint hier nicht die gleiche Sorgfalt auf die Abwärtskompatibilität zu geben, aber es ist einfach keine Option, bestehende Kunden in einer zukünftigen Version absichtlich zu brechen (ich bin überrascht, dass dies bei dem viel größeren Marktanteil von ADO .NET überhaupt in Betracht gezogen wird). Wir können bestehende 4.x-Kunden nicht brechen und werden dennoch gebeten, CoreCLR zu unterstützen. Wo bleiben also bestehende 4.x-Bibliotheken, die die bestehende Abwärtskompatibilität beibehalten und auch CoreCLR unterstützen möchten? Sollten wir auch Dokumente/Beispiele duplizieren?

Warum ist es nicht in Ordnung, CoreCLR-Schnittstellen noch Mitglieder hinzuzufügen, es ist in Ordnung, sie vollständig herauszureißen?

Der Oberflächenbereich in .NET Core muss mit .NET Framework binärkompatibel sein, damit Erstanbieter und Drittanbieter auf .NET Core aufbauen und Portabilität ohne Änderungen in .NET Framework ausführen können. Das Hinzufügen von Membern zu Schnittstellen verstößt dagegen, da Consumer dieser Member fehlschlagen würden, wenn sie unter .NET Framework ausgeführt würden.

Ich argumentiere nicht für das Entfernen oder Hinzufügen dieser Schnittstellen, ich wollte nur einige Hintergrundinformationen dazu hinzufügen, warum das Design dort gelandet ist, wo es ist. Ich überlasse das den aktuellen Besitzern, darunter @saurabh500 .

Um den Thread zusammenzufassen: Der Grund, warum Microsoft Ihrer Meinung nach diese Schnittstellen portieren sollte, besteht darin, dem Ökosystem eine einfache Portierung auf .NET Core zu ermöglichen und gleichzeitig die .NET Framework-Implementierungen beizubehalten?

besteht darin, dem Ökosystem eine einfache Portierung auf .NET Core zu ermöglichen und gleichzeitig die .NET Framework-Implementierungen beizubehalten?

Jawohl.

Um den Thread zusammenzufassen: Der Grund, warum Microsoft Ihrer Meinung nach diese Schnittstellen portieren sollte, besteht darin, dem Ökosystem eine einfache Portierung auf .NET Core zu ermöglichen und gleichzeitig die .NET Framework-Implementierungen beizubehalten?

Jawohl. Externe APIs sind jetzt kaputt, wenn ich meine Codebasis (LLBLGen Pro) auf corefx portiere: Ich muss dann 2 APIs freigeben oder die vorhandene Codebasis für alle meine Benutzer brechen.

Es könnte für euch in Ordnung sein, unsere Sachen kaputt zu machen, da ihr den Schmerz nicht spürt, wir tun es. Für mich ist es nicht in Ordnung: Ich muss entweder mit einer abgeschlachteten Codebasis leben und 2 APIs pflegen, die dasselbe tun, ODER den Code meiner Benutzer brechen, weil Sie dachten, das sei in Ordnung.

Ich verstehe auch nicht, warum Schnittstellen keine Version haben, es ist nur eine Schnittstelle, so wie eine Klasse auch eine Schnittstelle hat. CoreFX kann die asynchronen Methoden perfekt zu den Schnittstellen hinzufügen.

Der Oberflächenbereich in .NET Core muss mit .NET Framework binärkompatibel sein, damit Erstanbieter und Drittanbieter auf .NET Core aufbauen und Portabilität ohne Änderungen in .NET Framework ausführen können. Das Hinzufügen von Membern zu Schnittstellen verstößt dagegen, da Consumer dieser Member fehlschlagen würden, wenn sie unter .NET Framework ausgeführt würden.

Einfache Lösung: Fügen Sie die Schnittstellen so hinzu, wie sie jetzt sind. Und wenn Ihnen alle klar geworden sind, dass diese obige Regel eigentlich ziemlich dumm ist, können Sie die Methoden, die Sie vor langer Zeit zu den Schnittstellen benötigt haben, zu den Schnittstellen hinzufügen und weitermachen.

Ich arbeite lange genug mit MS-Software, damit Regeln wie die oben genannten auf dem Papier großartig sind, aber in der Praxis gebrochen werden, sobald ein wichtiges MS-Team sie brechen muss. Wenn Sie so "offen" und "anders" sind, wie Sie sagen, im CoreFX-Marketing- / PR-Hoopla sind, zeigen Sie es. Alles, was ich in Bezug auf System.Data und CoreFX sehe, ist 'was MS braucht, wird getan, was alle anderen brauchen, ist auf dem Rückweg oder wird ignoriert'.

Eine andere Sache, die ich vergessen habe zu erwähnen: Fowler hat gestern auf Twitter erwähnt, dass jeder seine Sachen portieren muss. Ich muss für die Portierung meiner 500.000 LoC-Codebasis auf CoreFX selbst bezahlen, es kostet Zeit und Mühe und nimmt Zeit für andere Funktionen in Anspruch. Zusätzliche Reibung, die völlig künstlich ist (es ist eine neue Plattform! Wie kann es restriktive Regeln geben?) hilft wirklich überhaupt nicht: Es verursacht zusätzliche Wartungskosten, benötigt zusätzliche Zeit zum Portieren des Codes und Testen und belastet unsere Benutzer zusätzlich.

All das liegt außerhalb Ihres Rahmens und scheint nicht Ihre Sorge zu sein. Aber eines vergisst man: Was _wenn_ wir unseren Code nicht portieren und bei mir mehr Leute? Ich bin bereit, Zeit und damit mein eigenes Geld zu investieren, um meine große Codebasis auf Ihr neues glänzendes Framework zu portieren, aber es tut mir leid, es zu sagen, wenn ich auf ein Problem stoße, stoße ich auf Einschränkungen, seltsame Regeln und endlose Debatten, die in Stille enden . Iow: Ich fühle mich sehr allein gelassen, während Sie gleichzeitig so dringend wollen, dass uns Ihr neues glänzendes Gerüst gefällt.

Wie ich schon vor langer Zeit sagte : Verkaufe mir dieses Framework, dieses neue CoreFX. Nun, Reibung aufrechtzuerhalten und viel bewegten und weggenommenen Käse einzuführen, schafft keinen großen Anreiz, viel Zeit (und Geld) dafür zu investieren.

Nur meine 2 Cent.

@FransBouma Bitte versuchen wir, dieses Gespräch professionell, produktiv und auf Fakten zu konzentrieren.

Ich argumentiere nicht für oder gegen das Hinzufügen der Schnittstellen. Es ist jedoch nicht kompatibel, Methoden zu Schnittstellen hinzuzufügen. Gehen wir das durch:

1) Fügen Sie IDbConnection.OpenAsync zu .NET Core hinzu
2) Jeder, der diese Methode aufruft, kann jetzt nicht auf .NET Framework ausgeführt werden (wodurch ein Kernprinzip/Ziel verletzt wird, das ich oben genannt habe). Dies bricht auch den XAML-Designer und einige andere VS-Features, die genau auf dieser Tatsache beruhen.
3) Um .NET Framework auf den neuesten Stand zu bringen, liefern wir eine neue Version von .NET Framework "4.7" mit IDbConnection.OpenAsync
4) Jeder einzelne Typ, der IDbConnection vor dem Hinzufügen dieser Methode implementiert hat, kann jetzt nicht in .NET Framework "4.7" geladen werden.

Aus diesem Grund können wir Schnittstellen keine Methoden hinzufügen.

Wenn ich meine Frustration darüber behalte, wie die Dinge in Bezug auf die Kommunikation von MS-Problemen für mich laufen, werden Sie alle nichts davon wissen und denken, dass alles nur Rosen und Regenbögen ist. Wenn das unprofessionell aussieht, ist es mir egal, ob MS mich für einen Profi hält oder nicht.

Das heißt: Ich bin nicht mit den Interfaces verheiratet, also wenn sie weg sind, macht mich die Tatsache, dass es fortan Klassen und keine Interfaces mehr gibt, mit denen man theoretisch arbeiten kann, nicht zu einem traurigen Panda: Was getan werden soll, kann kann theoretisch auch über die Basisklassen erfolgen, heute wie heute spielen alle großen ADO.NET-Anbieter nett und leiten sich von den Basisklassen ab (dies war in der Vergangenheit IIRC nicht der Fall, wobei ODP.NET eine Schnittstelle implementiert hat, aber nicht abgeleitet von der Basisklasse). Dies ist auch der Grund, warum ich oben in diesem Thread anfangs nicht wirklich dachte, dass es eine große Sache ist, sie zu entfernen. Seitdem hatte ich etwas Zeit, darüber nachzudenken, und ich denke, es _ist_ eine große Sache.

Wir leben nicht in einem Vakuum auf dem Mars und Middleware / Frameworks an der Unterseite des Stapels jetzt ein Problem hat: Benutzer der aktuellen .NET - Vollversionen dieser Frameworks mit ihnen auf CoreFX behalten wollen , wie sie diese Frameworks kennen. Sie auf CoreFX zu portieren ist jedoch aus einer Vielzahl von Gründen eine große PITA, einer davon sind häufig verwendete Schnittstellen, die in öffentlichen APIs verfügbar sind, die auf CoreFX nicht vorhanden sind (und der Grund für diesen Thread).

Alleine aus diesem Grund würde ich die Schnittstellen gerne wieder sehen. Für mich persönlich nicht aus technischen Gründen (zB Async braucht Basisklassen, das ist schon ein Durcheinander). Ich weiß, dass ihnen bestimmte Methoden fehlen, aber das ist Ihr Problem, nicht meines. Das Entfernen macht das zu meinem Problem und (jetzt paraphrasierend) die MS-Antwort darauf lautet: Hände hochwerfen mit "Geht nicht!". Aber diesen Luxus habe ich nicht. Sie haben dieses Chaos geschaffen, Sie lösen es. Du willst, dass ich meinen Code portiere, viel Zeit und Geld investiere (das ich selbst bezahlen muss) um dein neues Framework zu unterstützen, warum machst du dann _dein_ Problem _mein_ Problem?

Betrachten Sie Ihr 4-Schritte-Szenario: Das Hinzufügen von Methoden zu Schnittstellen ist kein Problem, WENN Sie CoreFX als separates Framework sehen. Und ist das nicht trotzdem so? Es ist das gleiche wie beim Compact Framework vor all den Jahren (auf das ich mein Framework portiert habe, und ich habe dann ein paar harte Lektionen gelernt, die mir sagen, dass die Portierung auf CoreFX nicht einfach, schnell und einfach sein wird und zwei Codebasen beibehalten wird wird es auch nicht): Wir beginnen mit 1 API, dann hat jemand etwas vergessen oder ein Team innerhalb von MS braucht etwas, und Viola eine Breaking Change, auf die nur eine Handvoll Low-Level-Stack-Entwickler stoßen und so weiter und die beiden Wege werden sich trennen.

(Beispiel: Compact Framework hat 'SerializableAttribute' vergessen. Sie fügten hinzu, dass ein Dummy-Attribut in einer späteren Version nichts tut, aber Code brach, der davon ausging, dass er nicht vorhanden war und der seinen eigenen definierte)

Das Aufteilen von Straßen ist jedoch verständlich: Der Versuch, die Dinge kompatibel zu halten, ist zu restriktiv. Ich sage hier jetzt voraus, dass diese Regel in Zukunft gebrochen wird.

Dinge als „kompatibel“ zu betrachten, ist nicht nur auf der Ebene der API-Signaturen wichtig, sondern auch auf der Ebene des API-_Verhaltens_. Zu vertrauen, dass diese beiden (CoreFX und .NET Full) im API-Verhalten völlig gleich sind, ist zu riskant: Ein Framework-Entwickler muss die gleiche Funktionalität auf CoreFX und auf .NET Full testen, es gibt keine Möglichkeit, CoreFX allein zu testen genug, um davon auszugehen, dass der Code in Zukunft auf .NET zu 100% gleich funktioniert: Wie kann man das denn garantieren? Ein Call-Stack mit 20 Aufrufen tief auf CoreFX hat so viel anderen Code berührt als auf .NET full, ein kleines Detail hier und da und die Dinge ändern sich.

Der Punkt bei all dem ist: Es handelt sich um ein separates Framework: Es kann erwartet werden, dass sich Code, der gegen CoreFX kompiliert wurde, von Code unterscheidet, der gegen .NET full kompiliert wurde.

Es gibt ein paar Situationen:

1) Ein Framework hat eine Codebasis, von der 100 % auf CoreFX kompiliert werden. Dies gibt eine DLL, die auf .NET full lauffähig ist
2) Ein Framework hat eine Codebasis, von der 70 % auf CoreFX und 100 % auf .NET kompiliert werden. Dies ergibt 2 DLLs: eine für CoreFX und eine für .NET full. Es ist albern, die CoreFX-Version auf .NET vollständig auszuführen, da einem 30% der Funktionalität fehlen.

Im Fall von 1) verstehe ich Ihren Punkt. Im Fall von 2) (was für alle aktuellen .NET-Full-Targeting-Frameworks der Fall ist, darunter _alle_ ORMs von Drittanbietern) ist Ihr Punkt wirklich bedeutungslos, da sie sowieso mit 2 DLLs arbeiten müssen: effektiv 2 Codebasen, die müssen separat gepflegt, separat getestet und separat auf eigene neue Versionen migriert werden. Vor allem, wenn CoreFX neue Funktionen bekommt, die noch nicht Teil von .NET sind (was noch der Fall sein wird). (Übrigens: Wenn Sie DbDataReader.GetSchemaTable() zu CoreFX hinzufügen, das eine andere Datenstruktur als eine DataTable zurückgibt, da MS sich weigert, diese zu portieren, wird Code, der DbDataReader.GetSchemaTable auf CoreFX verwendet, auch auf .NET voll unterbrochen. Wenn Sie es anders benennen es wird brechen, da die Methode nicht vorhanden ist. Iow: Code bricht ab, wenn Dinge verwendet werden, die nicht in _beide_ Frameworks enthalten sind. Das bedeutet nicht, dass Dinge daher nicht in CoreFX vorhanden sein sollten).

Keine Schnittstellen auf CoreFX zu haben, macht die Situation des Frameworks in Situation 2) zu einer anhaltenden: Sie können nicht zu einem Framework werden, das zu 1) passt, weil zB ihre API die Schnittstellen offenlegt.

Microsoft schreibt seine eigenen Sachen so um, dass ihre Frameworks in Situation 1) zu Frameworks werden bricht jede App da draußen. Wir stecken also entweder in 2) fest oder benötigen ein wenig Hilfe von MS, um zu 1) zu wechseln.

Darum geht es hier. Sie sagten auf Twitter "Sagen Sie uns, was Sie brauchen". Wir machten. Wiederholt. Insbesondere bei System.Data findet keine Kommunikation statt. Nichts. Keine Zukunftspläne, keine Diskussion, was zu tun ist, nur Sackgassen und manchmal, wenn ein MS-Patient eingreift, ist es jemand, der kein wirkliches Interesse an der Angelegenheit hat. Ich schätze Ihre Zeit dafür, je mehr Hintergrund wir bekommen, desto besser, aber gleichzeitig ist es, als würde man mit einem Kollegen darüber sprechen: Es wird nicht gelöst, weil die verantwortlichen Personen abwesend sind und nicht an der Diskussion teilnehmen.

Wenn mich das frustriert klingen lässt und Gott bewahre 'unprofessionell', dann soll es so sein.

Danke fürs Zuhören. Übrigens mache ich mir keine Illusionen in Bezug auf System.Data: Es wird ein Zugwrack einer API sein, um Code zu portieren, und da es keine Kommunikation von den Verantwortlichen mit den Entwicklern gibt, die Schlüsselframeworks auf ihrer API schreiben, gibt es wenig bis gar keine Hoffnung wird sich verändern. Nicht deine Schuld, @davkean , es ist nichts Persönliches.

Ich muss die oben genannten Frustrationen über den Mangel an Kommunikation wiederholen. Wir benötigen auch Masseneinfügungen und Schemainformationen. Es gab seit über einem Monat keine Weiterentwicklung oder Kommunikation (siehe dotnet/runtime#15269 und dotnet/runtime#14302) dieser fehlenden Kernfunktionalität (in beide Richtungen). Microsoft bezeichnet den aktuellen Code jedoch als "einen Kandidaten für die Veröffentlichung", was selbst eine Botschaft von "es ist gut genug" ist. Es ist nicht. Es fehlen grundlegende Dinge, die hinzugefügt werden müssen, und wenn Sie diesen Threads folgen, müssen Sie aus ähnlichen Gründen der Versionierung

Schauen Sie sich das letzte Update auf dotnet/runtime#14302 an ("Warum ist DataTable/View/Set abwesend?"), es ist von vor 22 Tagen und fragt:

Ist System.Data.Common also jetzt für V1 von CoreCLR vollständig?

Ja, Frustration kann als unprofessionell rüberkommen. Der Ton und der Kontext des Textes sind scheiße und haben es immer getan, aber darauf sind wir hier beschränkt. Ich denke, jeder versucht hier, produktiv zu sein, aber wir bekommen von CoreFX-Seite einiges an Steinmauern in Bezug auf die tatsächlichen Fortschritte im System.Data Bereich und das heißt, um ehrlich zu sein, macht beide als Bibliotheksautor wütend und einen Benutzer dieser Bits.

Wir brauchen diese Kernfunktionsteile, Schnittstellen oder nicht – ich bin nicht hart auf Schnittstellen eingestellt und wir haben Dapper ohne sie portiert. Aber das Fehlen von DataTable, Ergebnisschemainformationen, Masseneinfügungen und dergleichen sind in einem "Release Candidate" inakzeptabel. Microsoft ist derjenige, der die Frustration darüber erhöht, den aktuellen Code als RC zu bezeichnen, wenn fast allgemein anerkannt wird, dass er nicht zur Veröffentlichung bereit ist. Ja, es ist nur ein Etikett, aber es ist sowohl ein falsches Etikett als auch eines, das die Dringlichkeit drastisch erhöht, weil es auf einem willkürlichen Zeitplan basiert (der hätte sich ändern sollen, um die Realität widerzuspiegeln). Ich glaube nicht, dass irgendjemand in diesem Thread für diesen Zeitplan verantwortlich ist, aber es lohnt sich, ihn als einen Hauptfaktor für die Frustration _level_ anzugeben.

Kommen wir zurück zum Wurzelproblem. Wir brauchen diese Teile, und viele unserer Millionen von Benutzern tun es. Also lass es uns reparieren.

Vergessen wir nicht NHibernate mit mehr als 1 Mio.

| IDbVerbindung | IDbBefehl | IDataReader |
| --- | --- | --- |
| 59 | 181 | 132 |

Die derzeitige Wahrnehmung ist, dass ADO.NET/CoreCLR neu gestaltet wird, um erstklassige Unterstützung für EF und SQL Server zu bieten, wobei der Rest des Ökosystems außer Acht gelassen wird – undurchsichtige Entscheidungen wie diese verstärken nur dieses Stereotyp .

Diese Wahrnehmung wird durch Dinge wie diese verstärkt: https://github.com/dotnet/corefx/issues/4646

Soweit ich das beurteilen kann, gibt es keine Möglichkeit , diese API außerhalb der SqlClient-Assembly sinnvoll zu implementieren.

Ich bin derzeit mit dem Testen ohne Schnittstellen ok. Aber ehrlich gesagt verstehe ich die Argumentation mit Schnittstellenversionierung und Kompatibilität nicht.

Ist die Idee von .NET Core nicht, dass es sich um ein neues Framework ohne Kompatibilitätslast handelt und dass es mit Ihrer Anwendung gebündelt ist, sodass Sie sich nicht mit solchen Problemen befassen müssen? Der Anbieter ist bereits inkompatibel mit denen in .NET, da Dinge wie Schemas und Datentabellen fehlen. Was würde also die Kompatibilität beeinträchtigen? Wenn sich die Oberfläche ändert, kompilieren Sie einfach gegen die neue Version und bündeln Sie sie mit Ihrer App.

Es hört sich einfach so an, als ob die meisten Ausreden für das Design nur Sorgen aus dem alten Framework sind, die nicht auf das neue anwendbar sind. Mal sehen, wie es in der Praxis aussieht.

Für Benutzer, die beabsichtigen, mehrere Frameworks zu unterstützen und in der Vergangenheit auf die Schnittstellen abzielen ... Ich möchte nur einen Haufen hässlicher Dinge teilen, die Dapper verwendet; Ich sage nicht, dass dies _gut_ ist, aber es reicht aus, um es kompilieren zu lassen. Natürlich wird es in einem riesigen Stapel von Dateien dupliziert ... Ich teile dies hauptsächlich, um noch eine weitere Auswirkung hervorzuheben:

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

Wir können keine Mitglieder zu Schnittstellen hinzufügen

Richtig, und das ist eine _gute_ Eigenschaft von Schnittstellen. Die Bevorzugung abstrakter Basisklassen ist der sicherste Weg, die API-Entropie voranzutreiben, anstatt sie zu bekämpfen.

Obwohl Sie die Prinzipien von OOD nicht _müssen_ , würde ich vorschlagen, dass Sie dies tun, wenn Sie OO-APIs erstellen. Kurz gesagt, das Interface Segregation Principle (ISP) besagt, dass _kein Client gezwungen werden sollte, von Methoden abhängig zu sein, die er nicht verwendet_.

Wenn Sie einer vorhandenen Abstraktion neue Methoden hinzufügen, verstoßen Sie automatisch gegen den ISP.

Sie können entscheiden, dass Sie sich nicht an SOLID halten müssen, weil Sie Microsoft sind und mit der BCL arbeiten Gegenargumente).

Nachdem ich seit 6-7 Jahren einige Open-Source-Projekte betreut habe, ist es meiner Erfahrung nach besser, die Schnittstellen klein zu halten. Wenn Sie einer Abstraktion neue Funktionen hinzufügen müssen, führen Sie eine neue Schnittstelle ein.

Wenn es hier Upvotes gäbe , hätte ich @ploehs Kommentar +1000

Aufschlussreicher Kommentar von @ploeh wie immer.

@FransBouma , wir werden die Ersetzungsfunktion von DbDataReader.GetSchemaTable() so hinzufügen, dass das gesamte Framework nicht beschädigt wird.
@NickCraver , SqlBulkCopy ist in unserem Zukunftsplan und wir arbeiten am Schema. Wir machen langsam Fortschritte beim Schema, da wir auch vernünftige Fortschritte machen müssen, damit unser Stack auf der x-Plattform funktioniert.
@mythz ,

@YoungGah Bitte aktualisieren Sie die damit verbundenen Probleme mit Informationen, damit diese Probleme auf dem neuesten Stand bleiben, z. B. https://github.com/dotnet/corefx/issues/1039 , da sonst die spärlichen Informationen überall verstreut sind. Es ist schön, dass Sie GetSchemaTable hinzufügen (und das Äquivalent von DbConnection, vergessen Sie das nicht!), aber es ist so schwer, Informationen darüber zu erhalten, was passieren wird und _wann_. Gibt es einen Plan, was wann hinzugefügt wird? Jetzt müssen wir nur noch einen Hinweis geben, dass in 'der Zukunft' noch etwas hinzugefügt werden könnte. Um ehrlich zu sein, ist das nicht wirklich toll, um eine Portierung einer Codebasis zu planen.

@FransBouma , ja, ich werde auch die anderen Threads aktualisieren. Was Ihre Anfrage bezüglich weiterer Informationen dazu betrifft, was und wann es verfügbar sein wird, verstehe ich voll und ganz, warum Sie es brauchen. Ich werde die Liste veröffentlichen, aus der hervorgeht, ob das Feature/die Funktionalität auf v1 verfügbar sein wird, absichtlich entfernt, nach v1 verfügbar sein wird oder das Design der zukünftigen Verfügbarkeit aussteht. Ich werde versuchen, es in den nächsten 2 Wochen zu posten. Was die Funktion Schema abrufen in DbDataReader und die Funktion DbConnection betrifft, so planen wir, sie für die rc2-Version verfügbar zu machen. Sollte sich der Plan aus unvorhersehbaren Gründen ändern, werden wir die Community aktualisieren.

Was auch immer hier passiert und für zukünftige Referenzen @YoungGah; IDataReader hat eine Abhängigkeit von DataTable, die eine Abhängigkeit von DataSet hat (die wir als separate Schicht betrachten - weil sie richtlinienlastig ist, im Gegensatz zu diesen Typen, die richtlinienfrei sind). zurückgebracht.

Ich würde hier eine andere Stimme für den Ansatz von @ploeh abgeben ; haben Schnittstellen, aber viel, viel feiner als die meisten Schnittstellen, die derzeit in der BCL enthalten sind. Dabei geht es sowohl um die Kommentare von

Warum können Sie nicht einfach eine neue Schnittstelle haben, die die alte erbt? Das alte veraltet. Entfernen Sie die alte in Zukunft. Zumindest können Sie es dann erweitern und bestehende Nutzungen nicht brechen.

Oder mehrere kleinere Schnittstellen. Ich komme gerade zu ploehs Kommentar.

Ich verstehe diese Notwendigkeit nicht, perfekte Kompatibilität mit dem ursprünglichen .NET zu haben. Hier gibt es nichts zu brechen, dies ist ein neues Framework und die perfekte Gelegenheit, die Verbindung zum Legacy-Code zu durchbrechen und Änderungen vorzunehmen, die lange Zeit benötigt werden, aber im ursprünglichen Framework schaden würden.

Als ich wieder Schnittstellen vorschlug, dachte ich nicht daran, die ursprünglichen 1.1-Schnittstellen mitzubringen, sondern aktualisierte Schnittstellen mit dem neuen Design. Es könnten sogar noch mehr davon sein, wie @ploeh sagte.

Schnittstellen ja, Legacy-Support wenn möglich, sollte aber an dieser Stelle keine Priorität haben.

Wiedereröffnung, da großes Interesse an diesem Thema besteht.

Hier gibt es nichts zu brechen, dies ist ein neues Framework und die perfekte Gelegenheit, die Verbindung zum Legacy-Code zu durchbrechen und Änderungen vorzunehmen, die lange Zeit benötigt werden, aber im ursprünglichen Framework schaden würden.

Die perfekte Gelegenheit also, die ursprünglich schlecht gestalteten Schnittstellen loszuwerden und auf Basisklassen zu standardisieren, wie es ADO.NET bereits tut? :Troll Gesicht:

Im Ernst, Sie haben jedoch die Wahl zwischen einer sauberen API oder Abwärtskompatibilität. Wähle eins. Ich sehe keine Möglichkeit, deinen Kuchen zu haben und ihn auch zu essen.

@JamesNK, aber das wäre genau der Punkt. Abwärtskompatibilität ist nicht erforderlich, Punkt.

Sie scherzen, aber die schlecht gestaltete API mit Schnittstellen war schlecht, weil sie schlecht entworfen wurde, nicht weil sie Schnittstellen waren. =) Es ist nicht so, dass Schnittstellen nicht überall im NET verwendet werden oder das ist etwas Neues. Entwerfen Sie das Ding diesmal einfach richtig und machen Sie weiter.

ADO.NET ist einer der stabilsten Codeteile in .NET. Es gab zwei oder drei gravierende Veränderungen in 15 Jahren. Es ist die perfekte API, um eine Schnittstelle zu stabilisieren und für alle einfacher zu machen.

Als Hinweis, dieses Thema hier ist auch eines der am häufigsten kommentierten Themen und hatte die gleiche lange Diskussion über Schnittstellen vs. virtuelle Methoden, Testbarkeit und so weiter.

@nvivo Ich muss zugeben, ich bin verwirrt. Nachdem wir festgestellt hatten, dass die Basisklassen die Testbarkeit ermöglichten, verwandelte sich dieser Thread in das Zurückbringen der Schnittstellen, um die Portierung von .NET Framework-Code nach .NET Core zu ermöglichen. Wie hilft es dabei, die Schnittstellen neu zu gestalten und etwas Neues einzuführen?

Warum können wir keine Originalschnittstellen für die Abwärtskompatibilität haben und mit allem fortfahren, wofür Sie sich entscheiden (entweder abstrakte Klassen oder kleine Schnittstellen)? Die ursprünglichen Schnittstellen könnten auf dem neuen Stack sitzen und die Abwärtskompatibilität bieten. Dieser Teil kann auch optional sein.
Das würde die Portierung vereinfachen und dennoch neue Wege ermöglichen.

@davkean

Ich kann nicht für alle antworten, die hier kommentiert haben. Ich schlug vor, Schnittstellen als API von ADO.NET zu verwenden, aktualisiert auf die neue aktuelle API. Ich habe nicht darum gebeten, die Originalschnittstellen und all die Probleme mitzubringen, die sie hatten. Der Zweck bestand darin, eine sauberer definierte API zu haben und es einfacher zu machen, sie zu simulieren und Code zu testen, der davon abhängt, hauptsächlich Datenabstraktionsbibliotheken und nicht Benutzercode.

Schnittstellen sind besser darin, APIs zu beschreiben, wie @ploeh weise gesagt hat, und viel einfacher zu verspotten. Das aktuelle Design ist schrecklich beim Spotten und erfordert, dass Sie fast den gesamten Anbieter als Bibliothek implementieren, um einfache Tests durchzuführen. Wenn das nicht jedem wichtig ist, kann ich das verstehen. Aber ich bin definitiv nicht damit einverstanden, dass es heute testbar genug ist. Testen, ob eine Methode A mit Parameter X aufgerufen wurde, indem überprüft wird, ob Methode B mit den Parametern X, Y, Z aufgerufen wurde, ist nicht ideal.

Nun, um zu sehen, wie Klassen bereits ein schlechtes Design erstellen:

  • Warum hat DbCommand eine DesignTimeVisible-Eigenschaft ? Ist die Unterstützung der Entwurfszeit eine Voraussetzung dafür, dass eine Verbindung als Verbindung definiert wird?
  • Warum gibt es ein Ereignis, um Statusänderungen zu
  • Ist ein ConnectionStringBuilder eine Voraussetzung für die Existenz eines Anbieters? Oder ist es eher eine nette Sache, VS-Assistenten sofort zum Laufen zu bringen?
  • Warum definiert DbDataReader Get Methoden für einige Kerntypen, fügt aber nicht für andere wie GetByteArray() und GetDateTimeOffset() ? Und ist es überhaupt erforderlich GetSql* Familie in SqlDataReader)?

Das sind alles rhetorische Fragen. Ich bin sicher, alle haben überzeugende Antworten und Dinge wurden bedacht. Der Punkt ist, dass das aktuelle Design eindeutig nicht als API-Definition gedacht wurde , etwas, das bei Schnittstellen wahrscheinlich mehr Aufmerksamkeit erhalten würde.

Ehrlich gesagt klingt die Diskussion über das Design von außen so, als ob sie so gelaufen wäre:

  • Lassen Sie uns diese Ereignisse hier behalten, weil es für Assistenten in Visual Studio einfacher ist, sofort zu arbeiten
  • Lassen Sie uns Schemaabrufmethoden entfernen, weil wir EF haben und das ist, was jeder auf der Welt verwenden sollte, Punkt.
  • Lassen Sie uns diese praktischen Methoden beibehalten, da sie seit .NET 1.1 unterstützt werden und wir die Kompatibilität NIEMALS brechen können!
  • lasst uns Datentabellen und Datensätze entfernen und jeden, der von .NET 1.1 kommt, trotzdem dazu bringen, seine gesamte Codebasis zu ändern!
  • Lassen Sie uns ein neues Anbietermodell aufbauen, das sich auf Cloud Computing, Community, Open Source und die Anwendungen von morgen konzentriert...
  • ... und bauen wir dieses Modell basierend auf den Anforderungen von gestern mit SqlClient als _alleinigen_ Testfall!
  • Lassen Sie uns ein brandneues Framework erstellen, das mit jeder Anwendung gebündelt wird, damit sich niemand Sorgen machen muss, dass Updates seine Anwendung _jemals wieder zerstören_!
  • .. dann lasst uns entscheiden, keine Schnittstellen hinzuzufügen, da alle Änderungen ihre Updates unterbrechen können!

Ja, da wird ein bisschen geschimpft und diese Diskussion führt nirgendwo hin =)... Wollte das aber nur aus der Brust bekommen. Es ist 2015, alles geht ständig kaputt und wir haben uns daran gewöhnt. Es wird in den nächsten Jahren 20 Updates für ASP.NET MVC geben, die viel mehr Breaking Changes als Schnittstellenänderungen in ADO.NET verursachen werden.

Ich liebe .NET immer noch und was Sie generell damit machen. Ich bin sicher, dass es eine Eile ist, .NET Core v1 rechtzeitig herauszubringen und nicht alles wird perfekt sein. Ich hoffe nur, dass die Community dies im Laufe der Zeit in andere Richtungen lenken kann und Sie keine Angst haben, Dinge zu zerstören, wenn wir uns bewegen.

Für ORM-Betreuer, warum nicht?

``` c#

wenn COREFX

Namensraum System.Data {
öffentliche Schnittstelle IDbConnection { ... }
}
```

und das Adaptermuster verwenden, um das neue System.Data mit Ihren eigenen Implementierungen zu umschließen? Tatsächlich könnten Sie ein Open-Source-Code-Paket dafür erstellen und teilen.

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

Das ist das Problem; Anstelle eines überlegten Ansatzes erhalten wir eine überstürzte Neufassung, um eine willkürliche Frist einzuhalten.
Es wäre eher spät, Q4/16, wenn es sein muss, als einen glänzenden neuen kaputten Mist zu haben. Es ist 2015 und alles bricht, ist eine schreckliche Rechtfertigung.

@thefringeninja , das entweder eine völlig unnötige und verwirrende Abhängigkeit hinzufügt, die nur mit der Hälfte der Systeme funktioniert (im gemeinsamen Fall), oder zu Namenskollisionen führt, die das Aufheben von extern alias erfordern (und viel Verwirrung, warum die Methode, die benötigt wird) a System.Data.IDbConnection akzeptiert nicht die unterschiedlichen, aber gleichen System.Data.IDbConnection , die Sie anbieten). Im Grunde würde das alles 10 mal schlimmer machen.

Können Sie ein konkretes Beispiel @mgravell geben ? Ich kann sehen, wie das funktioniert, wenn Sie Type.GetType("System.Data.IDbConnection, System.Data") oder vielleicht in PCL-Szenarien verwenden.

Wenn orm A System.Data.IDbConnection definiert und orm B definiert
System.Data.IDbConnection, dann gibt es jetzt zwei völlig unterschiedliche und
inkompatible Schnittstellen mit gleichem Namen/Namespace, Konflikt und
funktionieren nicht wirklich von einem der DB-Anbieter. Es löst nichts,
Grundsätzlich gilt. Schlimmer noch: Es wird an unbrauchbare APIs gemietet, an denen jemand erwartet, dass sie passieren
in einer SqlConnection oder NgpSqlConnection - und es funktioniert nicht.

Tatsächlich könnten Sie ein Open-Source-Code-Paket dafür erstellen und teilen.

Wenn es nicht System.Data.Common ist, bedeutet dies, dass DbConnection es nicht implementiert, und: Sie können sich auch nicht darum kümmern.

Sie würden nie einen Konsens für jeden ORM- oder ADO-. Noch schlimmer für High-Level-Frameworks (wie ServiceStack), die auf System.Data-Schnittstellen in Core-Bibliotheken verweisen (die jetzt definiert werden müssten) können kein ORM mehr verwenden, das nicht auf dieselben Schnittstellen verweist – was nein - man würde oder sollte.

Die einzige Möglichkeit, sicherzustellen, dass jede Bibliothek auf die gleichen System.Data-Schnittstellen verweist, besteht darin, dass sie mit den Basisklassen, die sie implementieren, wiederhergestellt werden - was mir immer noch nicht klar ist, welchen Schaden dies anrichtet.

@mgravell ah transitive Abhängigkeit, hatte das nicht bedacht. :+1:

Sie wissen, dass ich nicht verstehe, warum dies ein Problem ist, es sei denn, Sie koppeln Ihren Code eng an Code, der Ihnen nicht gehört. Schützen Sie Ihren Code vor Abhängigkeiten! Wickeln Sie es ein und abstrahieren Sie es weg. Es gibt viele Möglichkeiten, dies zu tun und Ihren Code testbar zu machen. Viele sind oben erwähnt. Sie Integrationstest die Bits, die Sie nicht besitzen. So funktioniert es. Sie sollten BCL-Objekte nicht verspotten! Wenn Sie es sind, ist Ihr Design nicht gut.

@nvivo Ich

@mythz Es gibt zwei Probleme, die wir mit den Schnittstellen hatten; 1) sie brachten eine (starke) Abhängigkeit von DataSet ein, die nicht zu richtlinienfreien Abstraktionen gehört und 2) sie brachten einen parallelen Satz von Abstraktionen zu den Basisklassen ein, sind aber mit der v1-Oberfläche gesperrt. Diese Verwirrung wollten wir vermeiden.

Ich stimme zu, dass es für Dritte nicht praktikabel ist, diese Schnittstellen bereitzustellen - sie müssen in den Kernabstraktionen implementiert werden, um nützlich zu sein.

Ich verstehe, dass dies Ihr ursprüngliches Problem ist, aber die Richtung hat sich jetzt zu einem Thread entwickelt, in dem es darum geht, die Schnittstellen der v1-Ära aus Kompatibilitätsgründen zurückzubringen. Konzentrieren wir uns darauf - wenn Sie Änderungen an der aktuellen Oberfläche besprechen möchten, reichen Sie bitte neue Probleme ein.

Das macht absolut keinen Sinn.

@nvivo bedeutet, dass Sie nicht derjenige sind, der das Problem hat, obwohl Sie es eingereicht haben - offensichtlich, wenn Sie es geschlossen haben. Das Problem besteht darin, die System.Data-Schnittstellen wiederherzustellen, um die Last der Unterstützung des gesamten Ökosystems zu verringern, das auf sie angewiesen ist. Sie scheinen in Ordnung zu sein mit:

Es ist 2015, alles geht ständig kaputt und wir haben uns daran gewöhnt.

Dies ist jedoch keine zufriedenstellende Strategie für diejenigen von uns, die vorhandene Codebasen und die Codebasen unserer Kunden unterstützen müssen, und sollte definitiv nicht die Standardstrategie für Verwalter von BCL-Bibliotheken sein, die sich auf alle .NET-Datenbanken auswirken.

Dies ist jedoch keine zufriedenstellende Strategie für diejenigen von uns, die bestehende Codebasen unterstützen müssen

@mythz Das ist aus dem Zusammenhang

Das Problem mit dem, was aus diesem Gespräch wurde, ist, dass es nicht viel Sinn macht. .NET Core ist ein neues Framework, kein Upgrade. Ein Großteil der vorhandenen vollständigen .NET-API ist nicht vorhanden und wird es auch nicht geben. Abwärtskompatibilität wird so sowieso nicht funktionieren.

@nvivo Genau dieses Gefühl trifft dieses Problem nicht auf Sie zu. Wenn Sie der Meinung sind, dass Abwärtskompatibilität nicht wichtig ist, haben Sie noch nie versucht, eine sinnvolle Codebasis zu unterstützen, die auf mehrere Plattformen abzielt – Sie sprechen auch nicht im Namen des CoreCLR-Teams. Diese Bibliotheken wurden nicht von Grund auf neu entwickelt. Wenn Sie oben lesen, werden Sie feststellen, dass die Ausführung von CoreCLR-Bibliotheken auf dem vollständigen .NET Framework ein Hauptziel ist. CoreCLR ist ein weiteres Plattformziel, bei dem die Portierung bestehender Bibliotheken entscheidend für den Erfolg ist, was das .NET-Team aktiv fördert und die diese fehlenden Schnittstellen derzeit behindern.

Bei all dem Gerede darüber, dass Schnittstellen nicht Versionsfreundlich sind, denke ich darüber nach, wie die Programmiersprache Go dieses Problem mit impliziten Schnittstellen umgeht.

Ich wurde gebeten, zu erweitern, was ich mit _politikfreien_ Abstraktionen meinte.

Grundsätzlich meine ich mit richtlinienfrei, dass die System.Data.Common-Abstraktionen fast keine Geschäftsregeln enthalten – sie stellen lediglich eine Form von APIs bereit, die ein bestimmter Anbieter implementieren muss. Dies steht im Gegensatz zu DataSet, das viele Geschäftsregeln und Code enthält. Richtlinienfreie Typen neigen aufgrund ihrer Konstruktion dazu, weniger häufig zu versionieren als Typen, die Richtlinien enthalten, da weniger Code und damit weniger Fehler und Designänderungen vorhanden sind. Wir möchten, dass Abstraktionen und Typen, die zwischen Bibliotheken von Drittanbietern _ausgetauscht_[1] zu seltenen Versionen[2] sind, die Anzahl der Probleme reduzieren, auf die Sie bei der Koordination von Abhängigkeiten über einen großen Paketgraphen stoßen. Sie können Exchange-Typen nicht als Teil Ihrer Anwendung einbetten oder zusammenführen, während Sie dies bei Nicht-Exchange-Typen tun können. Deshalb wollen wir sie aufgeteilt haben.

[1] Mit _ausgetauscht_ meine ich Typen, die dazu neigen, auf öffentlichen APIs zu erscheinen. Zum Beispiel betrachten wir Collection<T> als Austauschtyp, aber nicht List<T> .
[2] Die Verwendung von semantischer Versionierung für diese würde zu fast identischen Unterbrechungen wie oben mit den entfernten Schnittstellen führen, da Sie das Ökosystem "verzweigen"; Bibliotheken müssen eine Entscheidung treffen, ob sie vor oder nach der Pause auf die Bibliothek abzielen oder sich selbst teilen, um die Aufteilung zu bewältigen.

@mythz Ich muss Orms / Kunden als Teil einer kommerziellen App und vorhandenen Codes unterstützen .... Ich sage nicht, dass ich mit beiden Seiten einverstanden bin, aber Tatsache ist, dass dnx ein völlig neues Framework / eine völlig neue Laufzeit ist. Wenn es keine Schnittstellen gibt, befassen Sie sich damit ... mit einer Compiler-Direktive.

Wenn es keine Schnittstellen gibt, befassen Sie sich damit ... mit einer Compiler-Direktive.

Oh? Wie wäre es mit einer Methode, die IDataReader zurückgibt, oder einer Methode, die IDbConnection akzeptiert? Oder IDbTransaction? Wie wollen Sie das #ifdev umgehen, wenn Ihr _customers_-Code diese API verwendet?

'Kümmere dich darum'... was ist das für eine Arroganz?

Aktualisieren Sie ganz einfach das zugrunde liegende Paket (Ihre Organisation), um Ihren eigenen Typ oder den seit 2.0 unterstützten Basistyp zurückzugeben. Wenn Sie auf ältere Versionen von .net abzielen, können Sie stattdessen eine Anweisung verwenden, um die Schnittstelle zurückzugeben und sie als veraltet zu markieren.

Ja, es ist scheiße, aber ich bin sicher, dass sie (wirklich kluge Leute, die die ganze Zeit darüber nachdenken) es damals aus gutem Grund getan haben (zurück in .net 2.0). Kann ein Gespräch stattfinden und vielleicht wird sich das sicher ändern. Es ist nicht, auf eine Schaltfläche in einer schicken Benutzeroberfläche zu klicken und die Arbeit für sie zu erledigen. Aber gleichzeitig stimme ich Ihnen zu, dass ein Upgrade auf das neue Framework einfacher sein sollte, als eine Reihe von Typen zu ersetzen.

@FransBouma er ist wahrscheinlich auch jemand, der eine starke Namensgebung befürwortet.

@FransBouma @phillip-haydon kann Ihr Trolling an anderen Orten mitnehmen, Sie können nicht erwarten, dass Sie sich so verhalten und die Leute Sie ernst nehmen. Werfen Sie einen Blick auf meine Open-Source-Beiträge / Projekte, an denen Sie beteiligt sind, wenn Sie Zweifel haben ... Ich werde mich damit befassen müssen ... so oder so ...

Für das Protokoll bin ich gegen eine starke Namensgebung.

Komm damit klar...

Und du sagst, ich trolle?

" @FransBouma er ist wahrscheinlich auch jemand, der sich für eine starke Namensgebung einsetzt." ist off-topic und nicht sehr hilfreich für dieses Gespräch. Ja, es fühlt sich an wie dein Trolling..

Eine wichtige Tatsache, die in dieser Diskussion zu berücksichtigen ist, ist, dass die IDb*-Schnittstellen vor einem Jahrzehnt bei der Einführung der Basisklassen als API für ADO.NET in .NET 2.0 veraltet waren. Sie wurden nicht als veraltet markiert, aber alles, was seit dieser Zeit erstellt wurde, hängt stattdessen von den Basisklassen ab. App.config-Anbieter und Unterstützung für Verbindungszeichenfolgen kommen mir in den Sinn.

Wenn Sie Code haben, der von diesen Schnittstellen abhängt, codieren Sie gegen eine sehr veraltete API ohne Unterstützung für Dinge wie asynchrone Methoden, was bedeutet, dass Sie ihn trotzdem aktualisieren müssen, wenn Sie möchten, dass die Leute ihn weiterhin verwenden.

Aktualisieren Sie ganz einfach das zugrunde liegende Paket (Ihre Organisation), um Ihren eigenen Typ oder den seit 2.0 unterstützten Basistyp zurückzugeben. Wenn Sie auf ältere Versionen von .net abzielen, können Sie stattdessen eine Anweisung verwenden, um die Schnittstelle zurückzugeben und sie als veraltet zu markieren.

Es ist eine öffentliche API, die von vielen Tausenden von Anwendungen verwendet wird, und die API ist seit .net 1.0 öffentlich und wird verwendet. Es ist nicht „einfach“, im Gegenteil. Wir können nicht einfach die API ändern, weil Microsoft der Meinung ist, dass sie das tun müssen, um unser Leben besser zu machen: Es wird eine große Belastung für unsere Benutzer und damit für uns sein.

Ja, es ist scheiße, aber ich bin sicher, dass sie (wirklich kluge Leute, die die ganze Zeit darüber nachdenken) es damals aus gutem Grund getan haben (zurück in .net 2.0). Kann ein Gespräch stattfinden und vielleicht wird sich das sicher ändern. Es ist nicht, auf eine Schaltfläche in einer schicken Benutzeroberfläche zu klicken und die Arbeit für sie zu erledigen. Aber gleichzeitig stimme ich Ihnen zu, dass ein Upgrade auf das neue Framework einfacher sein sollte, als eine Reihe von Typen zu ersetzen.

Das ist die Sache: Es wird nicht als "neue Laufzeit" angesehen. Wenn das der Fall wäre, wie ich bereits besprochen habe, wäre es kein Problem. Microsoft hat jedoch die Idee, dass CoreFX-Targeting-DLLs auch auf .NET voll funktionieren müssen, daher gibt es kein neues Framework. Für Betreuer von Bibliotheken, die ebenfalls auf .NET full abzielen, mit Funktionen, die nicht in CoreFX enthalten sind (also viele der Bibliotheken heute da draußen), wird es viel "Spaß" geben, da sie 2 Versionen verwalten müssen. Nicht 2 oder 3 #ifdevs und das Problem ist gelöst, aber viele viele davon. Vielleicht ist es für Sie anders, da Sie Ihrem Kunden vielleicht die Stunden in Rechnung stellen können, die Sie für den Wechsel der API aufwenden müssen. Anders ist es, wenn Sie ein Allzwecksystem erstellen, das von vielen verwendet wird.

Wenn die Unterstützung kompakter Frameworks eine Richtlinie ist, wird die Unterstützung eines ORM auf vollständigem .net und CoreCLR eine schreckliche Zeitfresser sein, viel Frustration und eigentlich nicht viel gewonnen: Sie erhalten keine neuen Funktionen, Sie arbeiten nur um deren _Fehlen_ herum .

(und bevor jemand anfängt mit: "aber es läuft unter Linux, das wirst du gewinnen": unser Zeug läuft seit vielen Jahren auf Mono. Also nein, es ist nicht wirklich ein neues Feature, das es schon gab).

SellMeThisFramework. Oh, warum mache ich mir überhaupt die Mühe.

aber alles, was seit dieser Zeit gebaut wurde, hängt stattdessen von den Basisklassen ab

_hust_ Linq-to-SQL DataContext _hust_

Wie in der Tat viele Nicht-MS-ORMs, daher das Problem. Für adrett haben wir nur gebissen
den Aufzählungspunkt und migriert zu DbConnection. Wenn wir noch einmal Zeit hätten, ich
würde MS dringend empfehlen, [Obsolete] zu verwenden, wenn sie etwas überholt haben. Aber:
Wir können die Vergangenheit nicht ändern.

Es _ist_ jedoch ein sehr schmerzhaftes Problem zu lösen, zumal die meisten
Bibliotheksautoren müssen mit beiden APIs fortfahren (kompilieren in eine Richtung für
net40 usw. und eine andere Möglichkeit für DNX). Ich habe vorhin das schreckliche Durcheinander gepostet
das macht das adrett: es ist nicht schön, und es ist nicht so einfach wie

wenn.

Am 27. November 2015 um 20:07 Uhr schrieb "Natan Vivo" [email protected] :

Eine wichtige Tatsache, die in dieser Diskussion zu berücksichtigen ist, ist, dass die IDb*
Schnittstellen wurden vor einem Jahrzehnt als API für ADO.NET in .NET 2.0 eingestellt
als die Basisklassen eingeführt wurden. Sie wurden nicht als veraltet markiert, aber
alles, was seit dieser Zeit gebaut wurde, hängt stattdessen von den Basisklassen ab.
App.config-Anbieter und Unterstützung für Verbindungszeichenfolgen kommen mir in den Sinn.

Wenn Sie Code haben, der von diesen Schnittstellen abhängt, codieren Sie gegen a
sehr veraltete API ohne Unterstützung für Dinge wie asynchrone Methoden, was bedeutet
Sie müssen es sowieso aktualisieren, wenn Sie möchten, dass die Benutzer es weiterhin verwenden.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/dotnet/corefx/issues/3480#issuecomment -160198453.

Ich sehe den Punkt nicht, dass asynchrone Methoden aufgrund der Verwendung von Schnittstellen nicht hinzugefügt werden konnten. Sie hätten neue Schnittstellen für die asynchronen Methoden erstellen können. IAsyncDbCommand , IAsyncDataReader usw. Dann könnten Sie die Basisklassen dazu bringen, beide Typen von Schnittstellen zu implementieren.

Die ADO.NET-Benutzer verwenden entweder die asynchrone Version oder die synchronen Versionen, nicht beide. Das hätte also super funktioniert.

Für Bibliotheksentwickler spielt es keine Rolle, ob die Funktionalität wächst und die Schnittstellen gleich bleiben. Ist das nicht der Zweck? Führen Sie neue Schnittstellen für neue Funktionen ein. Die Arbeit mit Basisklassen ist nur ein Schmerz.

Darf ich den Thread hier einfach zusammenfassen?

Mehrere unabhängige anerkannte Community-Experten für .NET-Datentools,
darunter mehrere ORM-Autoren und -Betreuer sagen es Ihnen - ganz
klar - dass dies eine Reihe von Problemen darstellt. Ich glaube nicht
jeder von uns kennt die Feinheiten nicht oder ist naiv in der Programmierung
Prinzipien, und die meisten, wenn nicht alle von uns kennen die Hintergrundgeschichte gut,
weil wir damals dort waren.

Die offizielle Antwort scheint zu sein: "Es scheint uns in Ordnung zu sein und EF ist glücklich".
Ja, das wissen wir, weil die Entscheidung überhaupt erst gefallen ist.

Nun, wir haben alle unsere Meinung geäußert, auch wenn es nicht fruchtbar war.
Am 27. November 2015 um 20:41 Uhr schrieb "Jonas Gauffin" [email protected] :

Ich sehe den Punkt nicht, dass asynchrone Methoden nicht als a hinzugefügt werden konnten
Ergebnis der Verwendung von Schnittstellen. Sie hätten _neue_ Schnittstellen erstellen können für
die asynchronen Methoden. IAsyncDbCommand, IAsyncDataReader usw. Dann könnten Sie
lassen Sie die Basisklassen beide Typen von Schnittstellen implementieren.

Die ADO.NET-Benutzer verwenden entweder die asynchrone Version oder die synchrone
Versionen, nicht beide. Das hätte also super funktioniert.

Für Bibliotheksentwickler spielt es keine Rolle, ob die Funktionalität wächst und
die Schnittstellen bleiben gleich. Ist das nicht der Zweck? Neues vorstellen
Schnittstellen für neue Funktionen. Die Arbeit mit Basisklassen ist nur ein Schmerz.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/dotnet/corefx/issues/3480#issuecomment -160201361.

Dudes.. Aktualisieren Sie Ihren Code und heben Sie Ihre Hauptversion auf. Fertig.

Ja, aber es gibt keinen Grund, warum Sie diese Schnittstelle nicht mit einer Compiler-Direktive ausfüllen könnten, wenn Sie auf den Kern abzielen. Ich habe das mit einigen unserer PCL-Pakete gemacht.

Ich denke, Microsoft muss wiederholen, dass der Kern nicht voll ist, aber das hilft immer noch nicht. Ich denke, dass Microsoft einige Schnittstellen aufräumen muss, um ehrlich zu sein. Kürzlich gab es einen Blog-Beitrag, in dem es sehr inkonsistente Schnittstellen gibt und man nie weiß, welche man auswählen soll. Ich denke, dass die Definition einer zweiten asynchronen Schnittstelle scheiße ist. Wäre schön, wenn alles asynchron wäre..

Wäre schön, wenn das gesamte Framework durchgegangen wäre, um sicherzustellen, dass Dinge, die als veraltet markiert werden müssen, ... und als 4.6.2 veröffentlicht werden

@mgravell +100. Gut gesagt, 100% einverstanden.

Wie viel ist wirklich betroffen? Reden wir hier über coreclr? .NET-Desktop wird noch viele Jahre am Leben sein, bis coreclr aufholen kann. Genau für diejenigen, die sich beschweren, was decken Sie hier Verlust ab? Viele Leute sagen im Grunde, es ist das Ende der Welt.

@leppie Tatsächlich wird es ihn viele Jahre lang geben. Und wir werden diese Hacks und Workarounds auch in den kommenden Jahren in unserem Code beibehalten müssen. Der Streitpunkt ist hier die Beseitigung der gemeinsamen Brücke zwischen den beiden. Diese Arbeitsbelastung wurde auf alle Bibliotheksentwickler und nicht auf die BCL verlagert. Ich verstehe beide Seiten der Vor- und Nachteile der Benutzeroberfläche, aber ich verstehe nicht die Einstellung "es ist geringfügig, mach weiter" von einigen hier.

Lassen Sie uns hier direkt sein: Wenn alle Bibliotheksbenutzer dasselbe tun müssen, sollte es in der BCL stehen . Die Debatte lautet: "Wie sieht das aus?"

Auf der positiven Seite des Entfernens der Schnittstellen gibt es einen _zusätzlichen_ Versionierungsmechanismus mit dem neuen Paketierungsmodell, das jetzt im Spiel ist: Welche Klassen in X, Y und Z verfügbar sind, wird jetzt durch Tools viel besser unterstützt. ZB dotnet5.2 vs 5.4 aktuell. Aber auch da gibt es Nachteile. Zum Beispiel ist SqlClient immer noch nicht an dem Punkt, die Schnittstellen so zu implementieren, wie es heute ist (siehe dotnet/runtime#14302 und dotnet/runtime#15269), und angesichts dessen, was @YoungGah gesagt hat (es sei denn, ich

Was passiert also mit 5,6 (1,5)? Wenn den abstrakten Klassen mehr Mitglieder hinzugefügt werden, wird von jedem Datenprovider erwartet, dass er mit dem sich bewegenden Ziel Schritt hält, das sich mit jeder sich bewegenden Person ändern kann? Jeder Verbraucher muss eine Versionsbestimmung der in jedem verfügbaren Funktionen vornehmen? Müssen wir für jede zukünftige Version der Plattform eine Version der Assembly kompilieren, die der abstrakten Basis der übergebenen Klasse entspricht? Wie all dies mit Ergänzungen in Zukunft funktioniert, ist nicht 100% klar. Eine Schnittstelle, die sich nicht ändert, ist viel klarer. Darüber hinaus gibt es eine Dokumentation: Welche Funktionen, Methoden usw. in welchen Versionen _und Plattformen_ verfügbar sind, wird für alle Bibliotheksautoren in Zukunft ein großer Schmerzpunkt sein. Diese Sorge ist hier nur halb bezogen, aber sie ist im Spiel.

Momentan warte ich gespannt auf das Update in den nächsten 2 Wochen. Meine Befürchtung ist, dass es effektiv sein wird, da die Botschaft die ganze Zeit war: "Wir machen X, weil es für SQL und Entity Framework funktioniert, und das ist gut genug" - ohne eines dieser Worte zu verwenden. Die Frustration auf Seiten der Bibliotheksautoren ist für mich seit Monaten ein Mangel an Fortschritten (sowohl im Code als auch in der Diskussion) an diesen Fronten.

100% stimmen zu.

Als ich v2 (und höher) von SqlFu (mein Micro ORM) entworfen habe, musste ich entscheiden, wo die Erweiterungsmethoden angehängt werden sollen: an DbConnection/DbCommand oder an die Schnittstellen. Ich fand diese , und ich habe für die abstrakten Klassen beschlossen zu gehen.

Daher bin ich nicht SO betroffen, obwohl ich von der Entfernung von IDataReader betroffen bin, weil MS in ihrer Weisheit beschlossen hat, nicht ganz klar zu machen, welche Schnittstellen als veraltet behandelt werden sollten und welche nicht. Aber in meinem Fall ist es nicht schwer, die Schnittstelle zu ersetzen.

Ich sehe jedoch den Wert dedizierter Schnittstellen und denke nicht, dass es für MS so schwer ist, sie zu behalten/zurückzufügen. Wenn sie entscheiden, dass die alten Schnittstellen nicht so gut gestaltet sind, gut! Gestalten Sie die neuen genauer. Zumindest werden wir uns in Zukunft nicht mehr mit dem gleichen Problem befassen.

(Dies ist Thanksgiving-Woche in den USA, daher werden die Antworten von Microsofties ziemlich begrenzt sein, bis sie nächste Woche wieder im Büro sind.)

Ich möchte es nur wiederholen - damit Sie keine guten Vorschläge/Bugs in diesem Thread verlieren, wenn Sie Probleme mit den aktuellen Basisklassen/Oberflächenbereichen und/oder deren zukünftigen Version haben, reichen Sie bitte ein neues Problem ein. Lassen Sie diese Diskussion nur über die v1-Schnittstellen führen.

@NickCraver Ähnlich wie bei der Versionskompatibilität von .NET Framework gibt es keine grundlegenden Änderungen zwischen den Versionen der .NET Core-Oberfläche. Das Hinzufügen abstrakter Member zu den Basisklassen wäre beispielsweise ein Beispiel für eine Änderung, die _nicht_ vorgenommen wird.

@davkean, wie zuversichtlich bist du, dass das nicht passieren wird? Angesichts der Tatsache, dass wir eine unvollständige Oberfläche sehen und keine Garantien dafür haben, dass sich dies ändert, ist es schwer zu glauben, dass die fehlenden Teile nicht oder überhaupt später auftauchen. Ich würde jedoch denken, dass keine Breaking Changes eine _mehr_ wichtige Sache sind, von der ich sicher bin, dass die meisten Bibliotheksautoren hier auch davon ausgehen würden. Das bedeutet, dass es noch wichtiger ist, dass diese Gegenstände lange vor RTM-Treffern behandelt werden.

Für die Aufzeichnung gibt es separate Probleme auf der Oberfläche, siehe dotnet/runtime#14302 und dotnet/runtime#15269 mit den neuesten Updates von Microsoft am 25. September bzw. 2. Oktober - obwohl danach mehrmals nach Updates und Aktivitäten gefragt wurde. Das sind 2 Monate und 2 Veröffentlichungen, die gekommen sind, mit Stille. Dies ist, obwohl dotnet/runtime#14302 das aktivste Problem in diesem Repo ist (und dieses ist gerade das zweite geworden). Können Sie unseren Frust verstehen?

Ich bin absolut zuversichtlich, dass wir keine bahnbrechenden Änderungen vornehmen werden. Das Data Common-Team versucht, sie ohne Einführung von abstrakten Mitgliedern durchzuführen.

@NickCraver Es tut @YoungGah hat oben ein Update

@niemyjski

dnx ist ein komplett neues Framework/Laufzeit

Wenn Sie glauben, dass sich die dnx-Laufzeit- und Corefx-Bibliotheken aus dem Nichts manifestiert haben, unterschätzen Sie ernsthaft die Zeit, die für eine Neuentwicklung erforderlich wäre. Die Tatsache, dass CoreFx-Bibliotheken auf dem vollständigen .NET Framework ausgeführt werden, sollte Ihnen einen Hinweis darauf geben, dass es nicht völlig neu ist.

Wenn es keine Schnittstellen gibt, befassen Sie sich damit ... mit einer Compiler-Direktive.

Ja, aber es gibt keinen Grund, warum Sie diese Schnittstelle nicht mit einer Compiler-Direktive ausfüllen könnten, wenn Sie auf den Kern abzielen.

Wenn Sie sich die Mühe gemacht haben, die Kommentare zu lesen, bevor Sie in diesen Thread einsteigen, wissen Sie, dass es a) Gründe gibt und b) dies eine kaputte und nicht praktikable Strategie für Kern-BCL-Schnittstellen ist.

@nvivo

Eine wichtige Tatsache, die in dieser Diskussion zu berücksichtigen ist, ist, dass die IDb*-Schnittstellen vor einem Jahrzehnt bei der Einführung der Basisklassen als API für ADO.NET in .NET 2.0 veraltet waren.

Wenn dies der Fall wäre, hätten Sie kein Problem geöffnet, das ihnen sagt, dass sie wieder Schnittstellen verwenden sollen, von denen Sie wissen, dass sie vor einem Jahrzehnt von Basisklassen veraltet waren. Die Art und Weise, wie Sie eine API kommunizieren, ist veraltet, indem Sie das Attribut [Obsolete] , das der einzige Zweck für die Existenz ist. Wenn es nicht weit verbreitet ist, ist es nicht veraltet, unabhängig davon, was Sie jetzt denken. Die Tatsache, dass die meisten Nicht-MS .NET ORMs auf sie angewiesen sind, sollte einen Hinweis darauf geben, dass ihre Einstellung, wenn überhaupt, schlecht kommuniziert wurde.

Wenn Sie Code haben, der von diesen Schnittstellen abhängt, codieren Sie gegen eine sehr veraltete API ohne Unterstützung für Dinge wie asynchrone Methoden, was bedeutet, dass Sie ihn trotzdem aktualisieren müssen, wenn Sie möchten, dass die Leute ihn weiterhin verwenden.

Ein falscher Strohmann - das eine impliziert nicht das andere. Wir haben bereits Unterstützung für asynchrone APIs hinzugefügt.

Okay, diese ganze Sache mit einem sauberen Start ist großartig, aber darf ich eine Frage stellen: Welche Kompromisse wurden eingegangen, um Ihre eigenen Frameworks zu unterstützen? Welche Schrecken der Vergangenheit wurden migriert, weil sie beispielsweise benötigt werden, um Entity Framework zum Laufen zu bringen?

Es wäre eine Schande, die MicroORMs verschwinden zu lassen, sie machen .Net-Code etwas performant (EF ist ein unbrauchbares Biest für Anwendungen, bei denen 500 ms zum Laden einiger Zeilen nicht akzeptabel sind).

Was Interfaces vs. Basisklassen betrifft: Basisklassen sind großartig, solange alles, was jemals wiederverwendet werden kann, virtuell ist. Zum Beispiel ist eine der irritierendsten Designentscheidungen in WCF die ausgiebige Verwendung von versiegelten Klassen, die viele Funktionen enthalten. Angenommen, Sie müssen die Art und Weise, wie XML-Nachrichten behandelt werden, geringfügig anpassen (weil: Interop). Anstatt eine kleine Funktion zu erben und zu überschreiben, müssen Sie sie erneut implementieren. Im WCF-Beispiel wurde das S in SOLID übersprungen, sodass Sie normalerweise eine große Schnittstelle ohne die Tests implementieren müssen, die erforderlich sind, um die Produktionsqualität sicherzustellen.

Also: Basisklassen, die wir anpassen können, sind gut.

Ich bin absolut zuversichtlich, dass wir keine bahnbrechenden Änderungen vornehmen werden. Das Data Common-Team versucht, sie ohne Einführung von abstrakten Mitgliedern durchzuführen.

@davkean Das ist unmöglich zu garantieren, und das wissen Sie. ADO.NET ist ein Subsystem zur Kommunikation mit Software von Drittanbietern mit einer Vielzahl von Funktionen, die über eine gemeinsame API mit einigen Erweiterungspunkten bereitgestellt werden. Die Dinge ändern sich, sogar im Datenbank-Land, und diese Änderungen wirken sich auf die API aus, die zur Kommunikation und Nutzung dieser externen Datenbankdienste verwendet wird. Außerdem: Verhaltensänderungen _ist_ auch eine bahnbrechende Veränderung. Und die haben wir in den letzten Jahren auch in ADO.NET gesehen (zB zur Fehlerbehandlung).

Die gesamte ADO.NET-API ist voll von den Nebenwirkungen dieser Änderungen, die oft von SQL Server getrieben werden. es war kaum so, dass Dinge allgemein entworfen und dann in den SQL-Client verschoben wurden, sondern umgekehrt (es gibt zB nicht viele oder gar keine Features in den Basisklassen, die von SqlClient ignoriert werden). Hinzu kommt, dass Dinge, die von Drittanbietern benötigt werden, es nie in die API geschafft haben.

Kurz gesagt, es ist eine API, die zu Beginn mit .NET 1.0 ein allgemeines Design hatte (das sich in vielen Bereichen als ernsthafte Mängel herausstellte) und das seitdem mit Funktionen links und rechts gepatcht wurde, um die Änderungen in die Landschaft. _Die meisten_ davon sind noch in der API (wenn nicht alle). Und jetzt wird Microsoft eines entfernen: die Schnittstellen.

Durch das Entfernen eines zufälligen Teils der API ist absolut _nichts_ gewonnen: Dadurch wird keine Funktion hinzugefügt (Sie könnten die Zeit damit verbringen, anstatt zum Beispiel hierher zurückzudrängen), aber Code, der diesen Teil der API nutzt, _wird_ nicht funktionieren. Wenn der Sinn hinter all diesen Käsebewegungen darin besteht, "von vorne anzufangen", dann tun Sie es auf jeden Fall, aber tun Sie es, indem Sie die API neu gestalten, um sie zu einer echten Allzweck-API zu machen .

Aber das ist nicht getan. Niemand muss sich fragen warum, wir alle wissen warum. Wir wissen auch, dass wenn ein Team innerhalb von MS durch die Entfernung der Schnittstellen schwer verletzt worden wäre, sie gar nicht entfernt worden wären.

Wenn Microsoft neue Funktionen über Basisklassen hinzufügen kann, sodass Drittanbieter automatisch eine Form des Features implementieren (wie bei Async, wo die async-Methode auf die sync-Methode zurückgreift, wenn der Anbieter sie nicht implementiert), großartig: das bedeutet, dass wir ORM-Entwickler von Drittanbietern (und seien Sie ehrlich: viele viele Entwickler greifen auf _Ihre_ API über den Code von (Mikro-)ORMs von Drittanbietern zu) einfach auf eine Klasse abzielen und das war's.

Aber es ist nicht garantiert, dass Sie das tun. ZB hat sich innerhalb von Microsoft noch nie jemand damit beschäftigt, spezielle Funktionen für Oracle oder PostgreSql zu ADO.NET hinzuzufügen. ZB Verwendung von UDTs, Document Trees, multiple Resultsets durch Cursor, jeder ADO.NET-Provider muss seinen eigenen Weg finden, mit diesen Features umzugehen. Was ist, wenn (wann?) SQL Server ein Dokumentbaum-Feature zB mit JSON-Dokumenten bekommt, wird ADO.NET dann mit einer neuen API dafür aktualisiert? Wie Sie es in der Vergangenheit mit Fehlerberichten von ADO.NET-Anbietern getan haben?

Sie können solche Garantien nicht geben, und es ist unklug, hier zu sagen, dass MS in Zukunft nichts kaputt machen wird. Das haben sie immer und manchmal mussten sie sogar: Schließlich hat jede API Fehler und ADO.NET ist voll davon; so oder so wird sie irgendwann jemand "reparieren".

Um es noch einmal zusammenzufassen: Die Schnittstellen sind Teil von ADO.NET, wie auch die verpfuschten Teile an anderer Stelle in der API Teil von ADO.NET sind. Diese werden nicht entfernt, um die API zu reparieren, noch wird die API umgestaltet, um sie zu einer allgemeineren API zu machen: Sie wurde unverändert belassen, wobei einige Elemente wie DataSet/Tabellen-abhängige Elemente entfernt wurden, da diese nicht portiert sind (und dort) sind andere Themen, die mit ähnlichen Fortschritten diskutiert werden), außer ... Schnittstellen wurden entfernt.

Allein unter diesem Gesichtspunkt macht es schon keinen Sinn.

@mythz

Wenn dies der Fall wäre, hätten Sie kein Problem geöffnet, in dem Sie aufgefordert werden, zur Verwendung von Schnittstellen zurückzukehren, von denen Sie wissen, dass sie veraltet sind

Sie können das OP unmöglich lesen und verstehen. Diese Diskussionen werden zu religiös und Sie nehmen einfach Dinge an, die niemand gesagt hat.

Ich habe dieses Problem geöffnet, weil ich glaube, dass Schnittstellen besser darin sind, eine API zu beschreiben und beim Testen zu helfen. Wenn es fertig ist, sollten sie meiner Meinung nach nicht mit einer 15 Jahre alten API kompatibel sein, die ihre Probleme hatte. Abwärtskompatibilität war nie ein Punkt in dem Thema, bis Sie die Diskussion darauf verschoben haben.

Es ist nicht so, dass ich glaube, dass Dinge kaputt gehen sollten, nur um der Sache willen. Aber Schnittstellenversionierung ist ein Problem der Vergangenheit. Wenn corefx zwischen den Hauptversionen etwas ändert, werden die Hauptversionen voraussichtlich wichtige Änderungen enthalten. Wenn sie eine Schnittstelle zwischen Nebenversionen unterbrechen, ist das nur Schlamperei.

Wir haben bereits Unterstützung für asynchrone APIs hinzugefügt

Sie können eine asynchrone API nicht über einer Synchronisierungs-API hinzufügen. Wenn Sie dies mit IDbConnection oder IDbCommand getan haben, haben Sie es falsch gemacht. Wenn Sie diese Schnittstellen nicht verwenden, haben Sie eigentlich keinen Sinn, die Abwärtskompatibilität mit ihnen zu verteidigen.

Wir haben bereits Unterstützung für asynchrone APIs hinzugefügt

Sie können eine asynchrone API nicht über einer Synchronisierungs-API hinzufügen. Wenn Sie dies mit IDbConnection oder IDbCommand getan haben, haben Sie es falsch gemacht. Wenn Sie diese Schnittstellen nicht verwenden, haben Sie eigentlich keinen Sinn, die Abwärtskompatibilität mit ihnen zu verteidigen.

In ADO.NET haben sie das getan: Die Async-Methoden greifen standardmäßig auf die Sync-Varianten zurück. Auf diese Weise müssen alle ADO.NET-Anbieter, die Async nicht unterstützen (sprich: derzeit alle außer SqlServer), keine Dinge implementieren, die sie nicht unterstützen: Code von Drittanbietern in ORMs, die eine Async-API anbieten, können dagegen programmieren die Async-Methoden in ADO.NET und wenn der ado.net-Anbieter Async nicht unterstützt, wird es niemand wissen. Nun... Sie werden es wissen, weil es langsamer ist, aber davon abgesehen.

Jetzt ist es auch ein gutes Beispiel für das Fehlen jeglicher 'Design' oder allgemeiner Architektur in ADO.NET: Es gibt _keine_ Möglichkeit, einen Transaktions-Savepoint in der allgemeinen API zu erstellen. Obwohl fast _alle_ Datenbanken dies mit einer 'Save(string)'-Methode für ihre von DbTransaction abgeleitete Klasse unterstützen. Alle außer OleDbTransaction (da MS Access dies nicht unterstützt, ist das zumindest mein Verdacht).

Es ist nicht einfach, aber niemand hat gesagt, dass es einfach ist. Dieses Problem ist nicht neu, OleDB und ODBC beschäftigen sich seit vielen Jahren damit, JDBC hat einen Weg gefunden, es zu lösen, Microsoft muss das Rad nicht neu erfinden, um solche Dinge zu überwinden. Es ist auch nicht einzigartig im DB-Bereich: zB unterstützt jede Grafikkarte eine andere Untergruppe von Funktionen über ihre API, die dem Entwickler über Direct3D/X zugänglich gemacht wird. Es ist tatsächlich interessant, wie Designs in diesen anderen Welten ablaufen: Die API wird entworfen und die Parteien, die sie unterstützen müssen (JDBC-Treiber, OleDB-Treiberschreiber usw.), müssen diese implementieren. Ihr Treiber unterstützt X nicht? Ihr Treiber ist nicht mit X kompatibel. "Oracle unterstützt ADO.NET v10 nicht". Niemand innerhalb von Oracle will das lesen. Stattdessen ist SqlClient der Lead, und was vom Wagen fällt, wird zu ADO.NET hinzugefügt und das war's.

In ADO.NET haben sie das getan: Die Async-Methoden greifen standardmäßig auf die Sync-Varianten zurück.

Nein, ist es nicht. Die API macht asynchrone Methoden verfügbar, die standardmäßig auf Synchronisierungsmethoden zurückgreifen, aber Anbieter überschreiben mit echten asynchronen Vorgängen. Was @mythz angibt, ist, dass er IDbCommand und IDbConnection verwendet und dies tut.

Das ist nicht möglich, Punkt. Wenn Sie es tun, machen Sie es entweder nicht richtig oder Sie verwenden die Schnittstelle nicht. Sie können die Asynchronität nicht erfinden, wenn die zugrunde liegende API nicht asynchron ist.

Nein, ist es nicht. Die API macht asynchrone Methoden verfügbar, die standardmäßig auf Synchronisierungsmethoden zurückgreifen, aber Anbieter überschreiben mit echten asynchronen Vorgängen. Was @mythz angibt, ist, dass er IDbCommand und IDbConnection verwendet und dies tut.

Kein offizieller Anbieter außer SqlClient macht das, alle anderen, zB ODP.NET, implementieren keine Form von asynchronem Code und daher fällt der Aufrufcode auf die Sync-Varianten (die async-Methoden in DbDataReader/DbCommand usw., die tatsächlich Sync-Code ausführen) zurück ). Benutzercode ruft also eine asynchrone Variante auf, die unter der Haube Synchronisierungsvorgänge durchführt. Was dazu führt, dass in der Praxis keine Asynchronisierung durchgeführt wird (da der gesamte Code in der Praxis einfach synchronisiert wird). Vielleicht implementieren die Anbieter von devart eine asynchrone API in ihrer eigenen Implementierung, nicht sicher.

Wie auch immer, es geht nicht darum, es richtig zu machen, sondern um die Versionierung von APIs.

@nvivo

Ich habe dieses Problem geöffnet, weil ich glaube, dass Schnittstellen besser darin sind, eine API zu beschreiben und beim Testen zu helfen. Wenn es fertig ist, sollten sie meiner Meinung nach nicht mit einer 15 Jahre alten API kompatibel sein, die ihre Probleme hatte. Abwärtskompatibilität war nie ein Punkt in dem Thema, bis Sie die Diskussion darauf verschoben haben.

Okay, Sie wussten also, dass die Kernschnittstellen von ADO.NET vor 10 Jahren veraltet waren und alles in Basisklassen verschoben wurde vorhandene Schnittstellen sollten nicht mehr existieren, da Abwärtskompatibilität nicht erforderlich ist oder? klar, klingt legitim.

Wenn Sie eine Plattform voranbringen möchten, entwickeln Sie die APIs im Laufe der Zeit weiter und unterstützen sie parallel, sodass jeder die Möglichkeit hat, auch parallele APIs zu unterstützen und ihnen zu ermöglichen, ihren Weg und ihre Kunden damit zu planen. Wenn Sie sie ohne Vorwarnung ausreißen, wird das Ökosystem, das sich auf sie verlässt, unnötig zerstört und die Komplexität auf jede nachgelagerte Abhängigkeit verlagert.

Sie können eine asynchrone API nicht über einer Synchronisierungs-API hinzufügen. Wenn Sie dies mit IDbConnection oder IDbCommand getan haben, haben Sie es falsch gemacht. Wenn Sie diese Schnittstellen nicht verwenden, haben Sie eigentlich keinen Sinn, die Abwärtskompatibilität mit ihnen zu verteidigen.

Ich wünschte, Sie würden aufhören, diesen Thread mit Kommentaren zu Dingen zu verschmutzen, von denen Sie offensichtlich keine Ahnung haben. Lesen Sie den Quellcode, wenn Sie wissen möchten, wie die Async-APIs implementiert sind – und hören Sie auf, blindlings Unwahrheiten zu verbreiten. Es ist für eine Bibliothek von Drittanbietern unmöglich, System.Data-Schnittstellen zu erweitern. Wir bieten eine implementierungsunabhängige API, die zur Unterstützung aller wichtigen RDBMS die minimale Abhängigkeit offenlegt, die jeder ADO.NET-Anbieter in seiner nach außen gerichteten API implementiert – nämlich die Kernschnittstellen von System.Data. Asynchrone APIs sind Erweiterungsmethoden von IDbConnection, die hinter den Kulissen asynchrone APIs auf den konkreten ADO.NET-Anbietern nutzen, die sie unterstützen. Intern bestehen bereits konkrete Abhängigkeiten zu jedem unterstützten ADO.NET-Provider, unabhängig von der Async-Unterstützung. Ihr Vorschlag, dass wir "eigentlich keinen Sinn haben, die Abwärtskompatibilität mit ihnen zu verteidigen", ist unerfahren und völlig unbegründet.

Lassen Sie mich dies an die Microsoft-Seite des Zauns stellen (cc @davkean @YoungGah): Sagen wir, es ist eine perfekte Welt und es ist nie

Folgemaßnahmen:
Wenn die Antwort ja ist (an einem Punkt nach dem RTM wird es Änderungen geben), welche Art von Unterbrechungen würden wir dann sehen? Ergänzungen, neue Methoden? Wenn ich die Basisklasse für meinen Anbieter erbe, was passiert dann, wenn Sie eine widersprüchliche Methode hinzufügen, die Leute verwenden usw.?

Wenn die Antwort nein (nie) lautet: Warum fügen Sie die Schnittstellen nicht einfach wieder hinzu?

Dieser Thread ist ein bisschen damit beschäftigt, _jetzt_ zu diskutieren - was meistens eine gute Sache ist, weil dieses Zeug so schnell wie möglich repariert werden muss. Jeder Bibliotheksautor hier weiß, wie schwer es ist, nach einer Veröffentlichung etwas zu bekommen, und deshalb drängen wir so hart. Leider führt das Fehlen eines klaren Plans für _zukünftige_ Ergänzungen und Änderungen, falls vorhanden, zu einer eher unzureichend informierten Argumentation.

Was sind die Pläne für die Zukunft?

Wir sollten in diesem Fall keine Implementierung über abstrakte Klassen erzwingen. IMO

Microsoft wird keine Änderungen vornehmen, die für .NET 4.5 schädlich sind. Es ist ein Teil von Windows. Kompatibilität ist König.

Microsoft könnte Änderungen vornehmen, die in .NET Core nicht funktionieren und sich nicht auf 4.5 auswirken. Ich bezweifle, dass sie 1.0 RTM auf einem niedrigen Niveau wie ADO.NET veröffentlichen werden, aber die Messlatte liegt niedriger. Es ist nicht Teil von Windows und .NET Core-Versionen können nebeneinander bereitgestellt werden.

Abstrakte Klassen können geändert werden - das ist nicht kaputt. Fügen Sie einfach eine virtuelle Methode mit einer Standardimplementierung hinzu. Dies wurde bereits mit den asynchronen ADO.NET-Methoden durchgeführt. Mit der Einführung von .NET Core glaube ich, dass Änderungen an freigegebenen Klassen zusammen mit .NET 4.5-Releases vorgenommen werden müssen, um die Kompatibilität zu wahren. Korrigiert mich jemand, wenn das falsch ist und nur für Schnittstellen gilt :grin:

@FransBouma

Das macht kein offizieller Anbieter außer SqlClient, alle anderen, zB ODP.NET, implementieren keine Form von Async-Code und somit greift aufrufender Code auf die Sync-Varianten zurück

Sie haben Recht, aber das ist kein Problem mit der API und mehr Faulheit oder Unverständnis der Implementierer. Der MySql-Connector beispielsweise hat alle seine asynchronen Methoden neu implementiert, indem er eine TaskCompletionSource erstellt und sie mit Synchronisierungsmethoden vervollständigt, was lächerlich ist. Sie könnten einfach die Hälfte ihrer Codebasis löschen und das gleiche Verhalten beibehalten.

Nicht zu sagen, dass Schnittstellen das lösen würden, aber kein Standardverhalten für Async zu haben, würde zumindest einige von ihnen dazu bringen, dies zu durchdenken. Die Tatsache, dass 90 % der sehr technisch versierten Leute asynchrone Vorgänge nicht verstehen, hilft auch nicht weiter.

Abstrakte Klassen können geändert werden - das ist nicht kaputt. Fügen Sie einfach eine virtuelle Methode mit einer Standardimplementierung hinzu. Dies wurde bereits mit den asynchronen ADO.NET-Methoden durchgeführt.

Das bricht. Es bricht für alle Bibliotheken, die diese Implementierung untergeordnet haben, ohne zu wissen, dass sie hinzugefügt wurde, und die Leute konsumieren dann dieses Denken. Oh diese Implementierung wird jetzt mit postgresql unterstützt BAM ERROR wtf passiert...

Die erzwungene Implementierung für eine DB-Abstraktion ist falsch.

Dabei spielt es keine Rolle, ob seine Schnittstellen oder eine Basisklasse. Es wird bahnbrechende Veränderungen geben. Aber eine erzwungene vordefinierte Implementierung ist falsch.

Polymorphismus funktioniert so nicht. Sie können eine Methode nicht überschreiben, ohne es zu wissen. Wenn Ihre Referenz eine DbConnection ist und Sie QueryAsync aufrufen, wird nur diese Methode oder was auch immer sie überschrieben wurde, aufgerufen. Eine Methode namens QueryAsync, die zufällig bereits in einer Unterklasse vorhanden ist, wird nicht aufgerufen.

Sie verwechseln das Überschreiben einer Methode mit den Versen, die sie mit demselben Namen verstecken.

@JamesNK

Wenn die Methoden abstrakt definiert sind, existiert keine Implementierung in der Basisklasse. Dies bricht den Vertrag für die Drittparteien, da sie die Implementierung in der Unterklasse hinzufügen müssen.

Wenn Sie die Methode virtuell machen, damit sie überschrieben werden kann, existiert eine Implementierung in der Basisklasse, die für die Unterklasse keinen Sinn ergeben könnte. Dies bricht immer noch, weil eine Implementierung existiert, die nicht vom Bibliotheksautor implementiert wurde. Sicher, Ihre App kann kompilieren, und alles ist gut, aber jemand ruft diese Methode auf und sie ist für die Unterklasse nicht gültig. Das ist falsch. Das ist eine erzwungene Implementierung, die nicht zur Unterklasse gehört.

Also eine abstrakte Klasse, in der eine Implementierung existieren kann, die nicht zur Unterklasse gehört. Oder Schnittstellen, bei denen keine Standardimplementierung für die Drittanbieter existiert.

@phillip-haydon deshalb ist es als virtuelle Methode implementiert, nicht als abstrakte Methode.

Sie können Dinge hinzufügen, die nur Unterklassen unterbrechen, die bereits ein Mitglied mit derselben Signatur (Name/Argumente) haben. Wenn die Argumente unterschiedlich sind, kann dies zu subtilen Fehlern führen, wenn Entwickler die Überladungen verwechseln.

Das ist eine erzwungene Implementierung, die nicht zur Unterklasse gehört.

Dann legen Sie es nicht dort hin.

@jamesnk

Legen Sie es nicht dort hin. Deshalb plädieren wir für den Wegfall von Schnittstellen.

Virtuell zu machen löst das Problem nicht. Es sollte keine vordefinierte Implementierung geben. Ende der Geschichte

@JamesNK In diesem Fall haben wir es nicht dort abgelegt, _Microsoft_ hat es dort eingefügt, indem wir es in die Zusammenfassung aufgenommen haben. Das Hinzufügen von Methoden, von denen angenommen wird, dass sie über _alle_ Provider hinweg funktionieren, die jemals erben, sehe ich nicht wirklich reibungslos oder effizient, selbst wenn sie technisch nicht kaputt gehen (ich gebe zu, dass "sollte neue" Kompilierungswarnungen _technisch_ nicht kaputt gehen). In den _meisten_ Fällen wird es einfach keine geteilte oder sofort geteilte Implementierung geben. Was ist also die Alternative? throw new NotImplementedException() in diesem virtuellen? Das ist kaum ein Argument dafür, dass es überhaupt existiert, es ist voller (Laufzeit-)Probleme.

Schauen wir uns heute an: Ich würde es viel lieber sehen, dass ein IDbAsyncConnection hinzugefügt wird, wenn ein Anbieter es unterstützt, als eine Reihe von Methoden, die unter der Decke synchron sind, was zu Verwirrung und Ineffizienz führt, was wir heute zu diesen haben Zusammenfassungen.

Ich würde es viel lieber sehen, dass eine IDbAsyncConnection hinzugefügt wird, wenn ein Anbieter sie unterstützt, anstatt eine Reihe von Methoden, die unter dem Deckmantel synchron sind, was zu Verwirrung und Ineffizienz führt

@ NickCraver +1000 dazu. Wie dieser Fehler hier, bei dem das Oracle-Team einfach nicht versteht, was asynchron bedeutet.

Das könnte man mit Schnittstellen machen. Das Problem dabei ist, dass Sie dann keine Argumente akzeptieren können, die mehrere Schnittstellen erfordern, zB brauche ich einen Typ, der sowohl IDbAsyncConnection als auch IDbConnection ist. Sie verlieren starke Eingaben und Sie müssen anfangen, nach Schnittstellen im COM-Stil abzufragen, was meiner Meinung nach nicht sehr benutzerfreundlich ist. Es ist ein Tool im API-Design, das seinen Platz hat, aber ich weiß nicht, ob ich es standardmäßig verwenden würde.

Wenn die Standardimplementierung NotImplementedException ausgelöst hat, ist es falsch, sie an die Basisklasse zu schrauben. Wie gesagt, dann stell es nicht da. Wenn Sie sehen, dass jemand dies tut, sprechen Sie ein Problem an.

Egal, ob es sich um Schnittstellen oder abstrakte Basisklassen handelt, meiner Erfahrung nach ist es sehr schwierig, einer Bibliothek, die ursprünglich nicht für sie entwickelt wurde, neue Funktionen hinzuzufügen, ohne die Welt zu zerstören.

@JamesNK vermutlich würde IDbAsyncConnection IDbConnection erben, aber das muss nicht unbedingt der Fall sein - sie könnten gemeinsame Mitglieder teilen oder von einer gemeinsamen Basis erben. In Dapper würden wir zum Beispiel wahrscheinlich wie folgt implementieren:

``` C#
IEzählbarAnfrage(diese IDbConnection cnn, CommandDefinition cmd)

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

Ich kann mir vorstellen, dass die meisten Bibliotheken mit sync/async-Methoden ähnliche Verwendungen und Implementierungen haben.

_Edit:_ Nachdem ich das eingegeben habe, wird mir klar, wie viel besser Async am Ende des Namens für all diese Dinge wäre ...

ADO.NET hat im Laufe der Jahre die folgenden wesentlichen Änderungen erfahren:

  1. Auf 2003 (1.1) haben sie eine bahnbrechende Änderung von 1.0 vorgenommen und sie neu gestaltet
  2. 2005 (2.0) wechselte man zum Anbietermodell mit den heute existierenden Basisklassen
  3. 2012 (4.5) haben sie die asynchrone Unterstützung hinzugefügt, die nichts anderes geändert hat, als neue Methoden hinzuzufügen, die die gleichen Dinge asynchron tun.

Zurück zu der Art und Weise, wie die API von 2003 definiert wurde, ist eine Änderung, die entweder die Kompatibilität unterbricht (was die Leute nicht wollen) oder die im letzten Jahrzehnt hinzugefügten Funktionen entfernt. Aber das Hinzufügen einer neuen Schnittstelle zu .NET Core mit dem aktuellen Design ist mit jeder .NET-Version _quellkompatibel_. Eine Neukompilierung ist alles, was Sie brauchen, um den meisten Code, der in den letzten 15 Jahren geschrieben wurde, funktionsfähig zu halten. Und Sie müssen sowieso neu kompilieren, um Corefx zu erreichen.

Diese API ist seit langem stabil. Es könnte als Schnittstellen umgestaltet werden, wenn die Leute wollten. Wie üblich gibt es hier keine technischen Probleme, es läuft auf Narben, Vorlieben und Ego hinaus.

Warum nicht die Schnittstellen zurückbringen und als veraltet markieren?

Obwohl diese Idee verworfen wurde, frage ich mich, ob Assembly-neutrale Schnittstellen in dieser Art von Situation hätten helfen können, siehe http://davidfowl.com/assembly-neutral-interfaces/ und dann ihre Implementierung
http://davidfowl.com/assembly-neutral-interfaces-implementation/

Ich denke, Assembly-neutrale Schnittstellen sind hier ein Ablenkungsmanöver; wenn etwas ist
passieren, ist dies eine völlig "gewöhnliche" Sache, da "allgemein" existiert. Außerdem
ist strittig, da das Feature verdampft ist.
Am 28. November 2015 um 17:38 Uhr schrieb "Shahid Khan" [email protected] :

Obwohl diese Idee fallen gelassen wurde, frage ich mich, ob die Montage neutral ist
Inferfaces hätten in dieser Situation helfen können siehe das
http://davidfowl.com/assembly-neutral-interfaces/ und dann ihre
Implementierung
http://davidfowl.com/assembly-neutral-interfaces-implementation/


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/dotnet/corefx/issues/3480#issuecomment -160323344.

Was ich beobachte:

  • Die Leute hinter der Idee von CoreClr (neues glänzendes Framework) haben eine völlig andere Denkweise als die Leute hinter der Implementierung (Abwärtskompatibilität mit 15 Jahre alter Codebasis ist König).

Was ich denke:

  • Indem Sie Schnittstellen entfernen, machen Sie die Dinge noch schlimmer .
  • Nichts ist veraltet, bis es mit [Obsolete] dekoriert wird. Und es spielt keine Rolle, wer zu welchem ​​Zeitpunkt was denkt. Dies ist der Vertrag und wenn Sie ihn einfach nicht erfüllen, dann nicht.

Was ich möchte:

  • Verwenden Sie Schnittstelle(n) als Basisoberfläche der API statt Basisklasse(n).

Was ich fühle:

  • Wir sind Ende 2015 und es ist frustrierend und traurig zu sehen, wie sich die Leute darüber streiten.

Schnittstellen können nicht versioniert werden.

Sicherlich lassen sich Schnittstellen einfach mit Schnittstellenvererbung versionieren? Und wenn es etwas ganz anderes macht; Nun, es ist eine andere Schnittstelle.

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

class SomeClass : IOldInterface, INewInterface, IDifferentInterface
{
}

Nennen Sie es einfach nicht IInterfaceV2 , IInterfaceV3 es muss erklären, was es hinzufügt.

Um [Obsolete] die alte Schnittstelle in einen Kontext zu setzen und einige neue Schnittstellen zu verwenden und sie so zu nennen, wie sie wirklich sind; anstatt die nicht asynchronen Methoden, die heutzutage normal erscheinen.

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

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

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

@abatishchev

Die Leute hinter der Idee von CoreClr (neues glänzendes Framework) haben eine völlig andere Denkweise als die Leute hinter der Implementierung (Abwärtskompatibilität mit 15 Jahre alter Codebasis ist König).

Vielen Dank für die Klarstellung, es sieht so aus, als müsste darauf hingewiesen werden. Im Allgemeinen glaube ich, dass MS-Teams sehr viel Wert auf Abwärtskompatibilität legen, was für die Entwicklung sowohl von Sprachen als auch ihrer Plattformen von entscheidender Bedeutung ist. Es ist nur so, dass Entscheidungen rund um System.Data nicht unter Berücksichtigung des breiteren Ökosystems getroffen werden – dem diese Kernabstraktionen gleichermaßen dienen sollten.

  • Indem Sie Schnittstellen entfernen, machen Sie die Dinge noch schlimmer.
  • Nichts ist veraltet, bis es mit [Obsolete] dekoriert wird. Und es spielt keine Rolle, wer zu welchem ​​Zeitpunkt was denkt. Dies ist der Vertrag und wenn Sie ihn einfach nicht erfüllen, dann nicht.

Genau.

Bezüglich der Schnittstellenversionierung. Korrigieren Sie mich, wenn ich falsch liege, aber ich dachte, dass der Sinn von CoreClr eine feinkörnigere, unabhängige Versionierung ist? Wandel brechen? Boom! Neue Hauptversion veröffentlicht.
Es sieht so aus, als würden Sie nach 15 Jahren Design-Erfahrung die gleichen Fehler wiederholen, aber jetzt haben Sie Nuget-Pakete unabhängig versioniert und veröffentlicht. Die obigen Argumente sind identisch mit dem guten alten monolithischen Framework, obwohl dies nicht mehr der Fall ist.
Wenn Abwärtskompatibilität ein Muss ist, können Sie diese Schnittstellen einfach nicht entfernen. Wenn dies nicht der Fall ist, hören wir auf, darüber zu sprechen und entwerfen die API von Grund auf, wobei wir diesmal auf die wichtigsten ORM-Autoren und andere erfahrene ADO.NET-Entwickler hören.
Dankeschön.

@abatishchev sehr gute Punkte. Das habe ich mich auch gefragt: Was soll das Argument der Rückwärtskompatibilität wirklich? Wenn CoreClr ein neues Feature hinzugefügt wird, läuft nicht alles, was es verwendet, auf .net full, also kann man sicherheitshalber nur das übliche Verhalten verwenden. (das hat nie gut geklappt).

Sorry für das lange Schweigen meinerseits.

Portierung auf .NET Core

Lassen Sie uns zunächst über den Elefanten im Raum sprechen, nämlich dass .NET Core nicht annähernd so viele APIs zur Verfügung hat, wie viele Leute – einschließlich uns – hoffen würden.

Ich arbeite mit meinem Team zusammen, um eine Reihe von Dokumenten zusammenzustellen, wie wir den Bereich der Portierung vorhandener Assets nach .NET Core angehen werden.

Wir planen, weitere Funktionen, die derzeit nur in .NET Framework / Mono vorhanden sind, auf .NET Core zu portieren. In diesem Dokument wird erläutert, wie wir das tun, wie wir Prioritäten setzen und wie die Mechanismen aussehen werden. Ich möchte nicht nur, dass diese Arbeit offen geschieht, sondern ich möchte auch, dass die Community uns dabei hilft, mehr Funktionalität zu portieren.

Breaking Changes

Es gibt einen Bereich, der viel Verwirrung stiftet, wenn über .NET Core gesprochen wird. Lassen Sie mich eines klarstellen:

Es ist keine bahnbrechende Änderung, wenn .NET Core über weniger APIs als .NET Framework verfügt.

Der Grund dafür ist, dass .NET Core eine neue Plattform ist und technisch über einen beliebigen Satz von APIs verfügen kann. Aber natürlich wollen wir kein willkürliches Set – das haben wir in der Vergangenheit gemacht. Das Ziel von .NET Core ist es, eine Geschichte zu haben, in der Benutzer Bibliotheken (und mit Konsolen-Apps bis zu einem gewissen Grad sogar Apps) erstellen können, die auf .NET Framework und .NET Core ausgeführt werden. Dies erfordert, dass es eine Teilmenge beider Plattformen gibt, die zu 100 % kompatibel ist. In diesem Zusammenhang werden Sie uns über Breaking Changes sprechen hören.

Darüber hinaus ist es unsere Absicht, in .NET Core eine hohe Kompatibilitätsleiste zu haben. Mit anderen Worten, wir planen nicht, API Breaking Changes zwischen einer Version einer .NET Core-API und einer anderen durchzuführen.

Schnittstellen

Das Hinzufügen von Mitgliedern zu Schnittstellen ist per Definition eine bahnbrechende Änderung. Einige Leute argumentieren, dass die Auswirkungen gering sind und dass es Möglichkeiten gibt, dies zu modellieren, aber so wie es heute aussieht, handelt es sich um eine binäre und quellenbrechende Änderung.

WinRT, das auf COM basiert und daher stark von Schnittstellen abhängig ist, löst dieses Problem, indem es weitere Schnittstellen wie IFoo , IFoo2 , IFoo3 . Es ist machbar, aber ohne eine Laufzeit- oder Sprachfunktion, die es erträglich macht, ist es sicherlich chaotisch. Bisher existiert eine solche Funktion nicht. Als Mitglied des Sprachdesignteams bin ich jedoch sehr an Vorschlägen interessiert. Andere Sprachen und Plattformen haben ähnliche Ideen in diesem Bereich, und ich schaue auch aktiv nach Optionen (wie Mix-Ins/Traits, Swifts Erweiterung-alles oder Standardmitglieder für Schnittstellen).

Da uns die Abwärtskompatibilität immer noch am Herzen liegt, bevorzugen wir im Allgemeinen abstrakte Basistypen gegenüber Schnittstellen.

ADO.NET-Schnittstellen

Lassen Sie uns nach alledem über die ursprüngliche Frage in diesem Thread sprechen: die Bereitstellung der ADO.NET-Provider-Schnittstellen.

Wie David erklärte: Wir betrachteten diese als veraltet, als die abstrakten Basistypen eingeführt wurden, was in .NET 2 / Visual Studio 2005 der Fall war. Für mich ist dies ein ausreichender Beweis dafür, dass wir die Schnittstellen auf .NET Core portieren sollten.

Wie bei allen neuen APIs müssen wir jedoch eines der Hauptziele von .NET Core berücksichtigen, nämlich einen komponentenbasierten Stack. Die Schnittstelle IDataReader hat eine Abhängigkeit von DataTable , die eine Abhängigkeit von DataSet . Wie in dotnet/runtime#14302 beschrieben, sind wir nicht dagegen, die Unterstützung für DataTable hinzuzufügen, aber wir betrachten DataSet Legacy. Wir könnten es jedoch immer noch als separates Paket hinzufügen, aber in beiden Fällen würde dies die Unterbrechung der Abhängigkeitskette von Interfaces -> DataTable -> DataSet erfordern. Ich werde mit @YoungGah zusammenarbeiten, um zu sehen, was wir dort tun können.

Würde dieser Ansatz die Bedenken ausräumen?

Wenn ich mich nicht irre, ist die einzige DataTable-Abhängigkeit in IDataReader die
GetSchemaTable()-Methode, bereits ausführlich in der DataTable besprochen
Kette. Ich gebe jedoch ohne weiteres zu, dass die Tatsache, dass es
Ich hoffe, zu einem späteren Zeitpunkt _einen_ Geist mit ähnlicher Funktionalität hinzuzufügen (ob
über DataTable oder nicht) macht es sehr umständlich, dies auf der
Schnittstelle, da eine spätere Erweiterung der Schnittstelle problematisch ist. Es wäre nicht
ganz so einfach wie "Methode vorerst entfernen, später etwas anderes hinzufügen"
Am 5. Dezember 2015 um 12:17 Uhr schrieb "Immo Landwerth" [email protected] :

Sorry für das lange Schweigen meinerseits.
Portierung auf .NET Core

Lassen Sie uns zuerst über den Elefanten im Raum sprechen, das ist .NET
Core hat nicht annähernd so viele APIs wie viele Leute – einschließlich
uns - würde hoffen.

Ich arbeite mit meinem Team daran, eine Reihe von Dokumenten zusammenzustellen, wie wir vorgehen
um sich dem Bereich der Portierung vorhandener Assets nach .NET Core zu nähern.

Wir planen, weitere Funktionen zu portieren, die derzeit nur verfügbar sind
existiert in .NET Framework/Mono bis .NET Core. Dieses Dokument fordert heraus
wie wir das machen, wie wir Prioritäten setzen und was die Mechaniker werden
Sein. Ich möchte nicht nur, dass diese Arbeit im Freien geschieht, ich würde es auch gerne tun
Aktivieren Sie die Community und helfen Sie uns, mehr Funktionalität zu portieren.
Breaking Changes

Es gibt einen Bereich, der viel Verwirrung stiftet, wenn die Leute darüber sprechen
.NET-Core. Lassen Sie mich eines klarstellen:

Es ist keine bahnbrechende Änderung, wenn .NET Core weniger APIs hat als .NET
Rahmen.

Der Grund dafür ist, dass .NET Core eine neue Plattform ist und es technisch möglich ist
einen willkürlichen Satz von APIs haben. Wir wollen aber natürlich keine
beliebige Menge
http://blogs.msdn.com/b/dotnet/archive/2014/12/04/introducing-net-core.aspx
– das haben wir in der Vergangenheit gemacht. Das Ziel von .NET Core ist es, eine
Geschichte, in der Leute Bibliotheken erstellen können (und mit Konsolen-Apps bis zu einem gewissen Grad)
sogar Apps erweitern), die auf .NET Framework und .NET Core ausgeführt werden. Dies
erfordert, dass es eine Teilmenge beider Plattformen gibt, die 100 %
kompatibel. In diesem Zusammenhang werden Sie uns über Breaking Changes sprechen hören.

Darüber hinaus ist es unsere Absicht, in .NET Core eine hohe Kompatibilitätsleiste zu haben.
Mit anderen Worten, wir planen nicht, API-Breaking-Änderungen durchzuführen zwischen
eine Version einer .NET Core-API und eine andere.
Schnittstellen

Das Hinzufügen von Mitgliedern zu Schnittstellen ist per Definition eine bahnbrechende Änderung.
Einige Leute argumentieren, dass die Auswirkungen gering sind und dass es Möglichkeiten zur Modellierung gibt
das, aber so wie es heute aussieht, handelt es sich um eine binäre und quellenbrechende Änderung.

WinRT, das auf COM basiert und damit stark von Schnittstellen abhängig ist,
löst dieses Problem durch die Schaffung weiterer Schnittstellen wie IFoo, IFoo2,
IFoo3. Es ist machbar, aber ohne Laufzeit ist es sicherlich chaotisch oder
Sprachfunktion, um es erträglich zu machen. Bisher existiert eine solche Funktion nicht.
Als Mitglied des Sprachdesign-Teams bin ich jedoch sehr daran interessiert
Vorschläge hören. Andere Sprachen und Plattformen haben diesbezüglich ähnliche Ideen
Raum, und ich prüfe auch aktiv Optionen (wie z
Mix-Ins/Traits, Swifts Erweiterung-alles oder Standardmitglieder für
Schnittstellen).

Da uns die Abwärtskompatibilität immer noch am Herzen liegt, bevorzugen wir im Allgemeinen
abstrakte Basistypen über Schnittstellen.
ADO.NET-Schnittstellen

Lassen Sie uns nach all dem über die ursprüngliche Frage in diesem Thread sprechen:
Offenlegen der ADO.NET-Provider-Schnittstellen.

Wie David erklärte: Wir betrachteten diese als veraltet, als die abstrakte Basis
Typen wurden eingeführt, die in .NET 2 / Visual Studio 2005 enthalten waren
dass man fest davon überzeugt ist, dass diese Schnittstellen entscheidend sind für
Portieren von ORM-Frameworks auf .NET Core. Für mich sind das ausreichende Beweise
dass wir die Schnittstellen auf .NET Core portieren sollten.

Wie bei allen neuen APIs müssen wir jedoch eines der folgenden Punkte beachten
Hauptziele von .NET Core, das einen komponentenbasierten Stack hat. Die
Schnittstelle IDataReader hat eine Abhängigkeit von DataTable, die a
Abhängigkeit von DataSet. Wie in dotnet/runtime#14302 beschrieben
https://github.com/dotnet/corefx/issues/1039 , wir sind nicht dagegen, hinzuzufügen
Unterstützung für DataTable, aber wir möchten DataSet wirklich nicht portieren. So
Das Hinzufügen der Schnittstellen erfordert das Aufbrechen dieser Abhängigkeit. Ich werde mit arbeiten
mit @YoungGah https://github.com/YoungGah, um zu sehen, was wir dort tun können.

Würde dieser Ansatz die Bedenken ausräumen?


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/dotnet/corefx/issues/3480#issuecomment -162115855.

Ja, IDataReader hat eine Abhängigkeit von DataTable, die eine Abhängigkeit von DataSet hat.

Wie bereits erwähnt, können wir keine Member aus Schnittstellen entfernen, daher müssten wir diese Abhängigkeit auf andere Weise auflösen; entweder indem Sie die Schnittstelle nicht portieren oder indem Sie die DataTable -> DataSet-Abhängigkeit unterbrechen.

Würde dieser Ansatz die Bedenken ausräumen?

Ja, die Wiederherstellung der ADO.NET-Schnittstellen auch ohne die Methode GetSchemaTable() würde die starken Abhängigkeiten von ADO.NET-Schnittstellenproblemen lösen, mit denen ich derzeit konfrontiert bin.

Ich gehe davon aus, dass die DataTable -> DataSet-Abhängigkeit durchbrochen wird, wenn dies bedeutet, dass auch GetSchemaTable() enthalten wäre. Dies wäre der bevorzugte Ansatz für diejenigen, die auf GetSchemaTable() angewiesen sind (das wäre also meine Stimme) - aber Ich würde den Entwicklern, die davon betroffen sind, mehr Gewicht geben.

@terrajobst danke für deine Zusammenfassung und das Teilen deiner Überlegungen.

@terrajobst danke für die Zusammenfassung und Erklärungen. Ich betreue Npgsql, schreibe also aus der Perspektive eines ADO.NET-Anbieters, nicht eines ORM.

In .NET Core scheint Microsoft den Wunsch gehabt zu haben, einige langjährige Legacy-Features von ADO.NET zu entfernen, nämlich DataTable/DataSet und die Schnittstellen. Dies führt zu einer besseren, saubereren API in der Zukunft, verursacht jedoch erhebliche Arbeit für Benutzer, die bereits von den Schnittstellen und der DataTable/DataSet-API abhängig sind.

Ich persönlich denke, dass das Beenden von DataTable/DataSet eine gute Sache ist und dass eine neue und bessere Metadaten-API eingeführt werden sollte (ich denke, dies gilt auch ohne das Beenden von DataTable/DataSet). Ich minimiere nicht
der Schmerz, der ORM (und anderen) Verbrauchern durch diesen Bruch verursacht, aber eine Sache, die Sie sich merken sollten, ist, dass .NET Core diese Gelegenheit bietet, wenn es jemals eine Gelegenheit zum Bereinigen und Einführen von Bruch gibt.

Ein weiterer frustrierender Faktor hierbei ist, dass das Beibehalten der ADO.NET-Schnittstellen auch das Beibehalten von DataTable/DataSet bedeutet. Mit anderen Worten, obwohl ich persönlich nicht sehr viel von dem Schnittstellenproblem halte, bedeutet es, DataTable/DataSet beizubehalten, und das scheint problematischer zu sein.

Da ich nicht weiß, wie viele ORMs es noch gibt, die noch von den Schnittstellen abhängen, und ich auch nicht weiß, wie aufwendig es für sie wäre, auf die Basisklassen umzusteigen, ist die Auswahl nicht sehr groß hier klar. Aber mein Bauchgefühl ist es, diese Gelegenheit zu nutzen und die Dinge aufzuräumen, auch wenn es bedeutet, dass einige Leute darunter leiden...

PS Was auch immer Sie tun, gehen Sie nicht den Weg der Schnittstellenexplosion, dh IFoo2, IFoo3. Das ist nur eine Nicht-Lösung.
PPS Wenn Sie sich entscheiden, eine neue Nicht-DataTable-Metadaten-API in .NET Core zu erstellen und möchten, dass .NET Core-Bibliotheken in .NET Framework ausgeführt werden, müssen Sie zusammen mit der neuen API ein neues .NET Framework veröffentlichen .NET-Core.

@terrajobst Danke, dass hast ;). Ich denke, das Kernproblem besteht darin, dass für ADO.NET kein Design vorhanden ist. Das gab es schon seit einiger Zeit nicht mehr und es zeigt sich in verschiedenen Teilen der API, die ein Sammelsurium von aufgefüllten Funktionen ist, ohne die Dinge länger als ein paar Minuten durchzudenken (wie es scheint). Ich stimme @roji in diesem

Das heißt, wenn sich die Dinge für ADO.NET nicht zum Besseren ändern (dh es bekommt ein echtes Design, bei dem eine allgemeine API entworfen wird, die dann auf den SqlClient spezialisiert ist und nicht umgekehrt! SQL Server, aber in anderen Datenbanken werden der allgemeinen API hinzugefügt und werden nicht dem Autor des ADO.NET-Anbieters überlassen), dann ist das nächstbeste, so viel wie möglich zu portieren, einschließlich der Schnittstellen und wir Entwickler von Drittanbietern #ifdef selbst um die Schlaglöcher, die übrig bleiben.

Die DataTable-Abhängigkeit kann jedoch ein Problem sein, da die IDataReader-Schnittstelle es schwierig macht, die Dinge abwärtskompatibel mit .NET full _if_ datatable in welcher Form auch immer nicht portiert zu halten. Aber ich denke, das ist sowieso verloren. Es wurde von MS mehrmals gesagt, dass .NET full nicht so viele / so häufige Updates erhält wie .NET Core. Wenn also etwas _neu_ zu .NET Core hinzugefügt wird, kann es niemand verwenden, da es die Bibliothek erstellt sofort inkompatibel mit .NET voll. Ich vermisse hier wahrscheinlich etwas, also korrigiert mich bitte, wenn das der Fall ist :)

Das allein macht schon eine merkwürdige Situation: Es muss eine Abwärtskompatibilität geben, aber in der Praxis scheint dies schwer zu erreichen und sowieso ein Ablenkungsmanöver. IMHO, wenn das zuerst angesprochen wird, kann das Ergebnis verwendet werden, um richtige Entscheidungen darüber zu treffen, was mit den APIs des .NET-Kerns zu tun ist, dh sie zu verbessern, anstatt alten, schlecht gestalteten Kram vollständig aus .NET zu ziehen. Das soll nicht heißen, dass alle APIs schlecht entworfen sind, aber mit ADO.NET (wie ich in einem früheren Beitrag beschrieben habe) wurden die Dinge seit vielen Jahren nicht richtig gemacht. Es ist vorzuziehen, einen sauberen Bruch zu machen und stattdessen ein System zu implementieren, das robuster (JDBC ist immer noch stark, ODBC funktioniert immer noch wie vor 25 Jahren) und sich an Veränderungen anpassen kann.

Wenn man etwas genauer darüber @FransBouma zur Abwärtskompatibilitätsanforderung sehr sinnvoll. Eines der Versprechen von .NET Core sind schnellere Iterationen dank der komponentenbasierten Nuget-Paketierung – statt .NET Framework-Updates, die einmal/zweimal im Jahr erscheinen, können .NET Core-Updates bei Bedarf veröffentlicht werden. Es scheint, dass der Wert davon stark eingeschränkt ist, wenn Updates die Abwärtskompatibilität mit .NET Framework niemals beeinträchtigen können ...?

Ich verstehe, dass Abwärtskompatibilität eine Anforderung ist, die weit über diese ADO.NET-spezifische Diskussion hinausgeht, frage ich mich nur.

Es ist umgekehrt @roji : kurze Iterationen werden ermöglicht, indem APIs nicht

Wenn Sie ein .Net-Entwickler sind und Ihr Build jede Woche bricht, weil sich die API des zugrunde liegenden Frameworks ständig ändert, wird es nicht lange dauern, bis Sie eine andere Plattform in Betracht ziehen.

Es handelt sich also um eine schnelle Iteration, die von nicht brechenden Änderungen angetrieben wird.

(bearbeitet)
Sie können nur ohne Breaking Changes iterieren, bis Sie z. B. etwas zu einer Klassenschnittstelle hinzufügen müssen, eine Verhaltensänderung (!) .net Core macht Ihren Code nicht kompatibel mit .net full, also macht es .net Core in diesem Sinne nicht mehr abwärtskompatibel mit .net full _für dieses Stück Code_. Was IMHO auf den .NET-Kern zurückzuführen ist, wird immer die gleichen (Klassen-)Schnittstellen und das gleiche Verhalten wie in .NET haben, bis zum letzten Byte (was IMHO nicht nachhaltig ist) oder neue Funktionen erhalten, die später zurückportiert werden (was buchstäblich das ist) MS sagte übrigens) zu .NET voll, was es effektiv nicht abwärtskompatibel macht. Es hängt natürlich davon ab, auf welcher Seite des Zauns Sie sich befinden: Wenn Sie sagen: 'Es gibt einen gemeinsamen Satz von (Klassen-)Schnittstellen X mit definiertem Verhalten B, und sowohl .NET Core als auch .NET implementieren diese vollständig und X & B werden gewinnen. t change in the future', bedeutet es dennoch, dass es außerhalb von X & B ein neues Framework gibt, das Neues bekommt und genau dort, wo sich Dinge ändern können und auch die Zukunft liegt.

Damit könnte man sehr weit gehen, zB dass die in X & B in .net core verwendeten Interfaces / Klassen eigentlich Wrapper um die neuen Klassen / Interfaces in .NET Core sind. Es liegt dann am Entwickler, der sie verwendet, entweder X & B oder die neuen mit besserem Design und ohne API gemeinsam mit .NET full zu verwenden.

Da wir uns bereits #ifdef um fehlende Dinge in X & B herumschlagen müssen, ist es bei der Unterstützung beider Frameworks IMHO vorzuziehen, einfach in der Lage zu sein, neue Schnittstellen / Klassen im .NET-Kern anzusprechen, wenn sich früher oder später das Verhalten ändert (vielleicht sogar sehr subtil , wie eine andere Ausnahme in einer bestimmten Situation) wird sowieso dort auftauchen, daher wäre es besser, Code auf .NET Core mit seiner _new_ API (nicht X&B) zu "portieren". Wir müssen sowieso portieren, zumindest sehe ich das so.

@ryanbnl , ich stimme @FransBouma zu. Der Punkt ist nicht, dass wir in der Lage sein wollen, APIs zu unterbrechen. Die Einschränkung der Ausführung von .NET Core in .NET Framework bedeutet, dass Sie nie etwas zu einer .NET Core-Schnittstelle hinzufügen oder einer abstrakten Basisklasse einen abstrakten Member hinzufügen können. Diese beiden Änderungen unterbrechen die Abwärtskompatibilität für jemanden, der .NET Core verwendet, nicht wirklich, sie unterbrechen die Kompatibilität mit .NET Framework.

@roji, es sei denn, es handelt sich um ein neues externes Framework-Paket (z. B. nicht GAC), wenn es sowohl mit Framework als auch mit Kern kompatibel sein und in seiner eigenen Kadenz ausgeführt werden kann; aber dann könnten sich für ORMs-Anbieter noch mehr Änderungen ergeben und der Name System.Data.IDbConnection ist bereits vergeben...

@benaadams das ist ein gültiger Kommentar - ich hatte nur Nicht-Nuget-Framework-APIs wie ADO.NET im Sinn. Diese scheinen jedoch genügend API-Speicherplatz abzudecken, um ein Problem zu sein - .NET Core kann keine dieser Methoden weiterentwickeln (sprich: Schnittstellenmethoden oder abstrakte Methoden hinzufügen), ohne dass sie nicht mehr lauffähig sind

Ich bin mir jedoch nicht sicher, was Sie mit IDbConnection meinen ...

@roji meinte nur ein neues Paket, das diese Typen System.Data.Database ; Um sowohl mit Core als auch mit Full kompatibel zu bleiben, könnten keine Typen neu definiert werden, die GACs im vollständigen Framework wären, oder es würde kollidieren.

Auf dem Nuget-Punkt; es gibt irgendeinen Grund dafür, dass dies nicht sowohl für Full als auch für Core in Nuget leben kann; und den aktuellen System.Data API-Beitrag 4.6.1+ verwerfen?

Es würde jetzt größere Schmerzen verursachen; aber einige Compat sind bereits kaputt, wo die Schnittstellen wegfallen, oder nur DataSet so dass einige Nacharbeiten für coreclr von ORM-Anbietern bereits durchgeführt werden müssen.

Eine völlig neue API, die in Nuget und außerhalb des GAC-Frameworks lebte, könnte abwärtskompatibel für die Verwendung mit netstandard1.2 sein, z Es ist wahrscheinlich eine bessere Zeit als später.

Angesichts der Tatsache, dass die neuen APIs für Achema und dergleichen im Spiel sind, wird die Bezeichnung DataSet nicht überkommen (oder DataTable ), sollte dies geschlossen werden? Es hört sich so an, als ob die Basisklassen der Weg nach vorne sind, basierend auf Kommentaren in dotnet/corefx#5609 und Typweiterleitung, was bedeutet, dass die Schnittstellen angesichts von GetSchemaTable() keine Verwendung haben und einige andere nicht dazu da sind, sie zur Kompatibilität zu bringen ...ist das fair zu sagen?

Soll was geschlossen werden? Wenn wir wegen der DataTable/DataSet-Abhängigkeit kein GetSchemaTable() , ist das eine Sache, aber die Schnittstellen sollten trotzdem wiederhergestellt werden (ohne GetSchema, falls erforderlich) und die Portierung vorhandener Codebasen mit tiefen Abhängigkeiten erleichtern. Die fehlenden Schnittstellen sind ein Blocker, ich warte immer noch auf eine Freigabe damit, bevor wir mit der Arbeit an der Unterstützung von dnx/core beginnen können.

Ich stimme @mythz zu , die Schnittstellen sind ein anderes Thema und sehr wichtig. Vielleicht nicht für die meisten Benutzer, aber dieselben Benutzer verwenden Code, der von einer kleinen Gruppe geschrieben wurde und dieser Code _ist_ auf diesen Schnittstellen (sowie anderen wichtigen fehlenden ADO.NET-Funktionen wie DbProviderFactory) angewiesen.

Um ehrlich zu sein, habe ich angesichts des extremen Strebens nach einem 'RTM'-Label wenig Hoffnung, dass wir mit 1.0 eine solide API bekommen. Es wird wieder wie bei .NET 2.0 sein: Alle Fehler der ersten Version werden dann korrigiert.

@FransBouma

Das Hinzufügen der Schnittstellen zu .NET Core wäre eine zusätzliche Änderung. Selbst wenn es nicht den Schnitt für V1 schafft, könnte es in jeder folgenden Version hinzugefügt werden, sogar in 1.1.

alle Fehler der ersten Version werden dann korrigiert.

Nichts für ungut, aber so funktioniert Software.

@terrajobst

Selbst wenn es nicht den Schnitt für V1 schafft, könnte es in jeder folgenden Version hinzugefügt werden, sogar in 1.1.

Ja, es ist nicht so, dass es technisch nicht möglich wäre, es ist so, dass die Ergebnisse (oder das Fehlen davon) (weitreichende) Konsequenzen haben, unter denen Microsoft nicht leidet, das sind wir. Dafür habe ich bisher wenig Apathie gesehen. Es ist alles cool und aufregend, an neuen Frameworks zu arbeiten, aber es wird nicht in einem Reinraum für ein neues Publikum entwickelt. Es ist auch nicht so, dass es keine Geschichte gibt, aus der man lernen könnte, im Gegenteil.

Nichts für ungut, aber so funktioniert Software.

Sehen Sie, genau das meine ich oben: Sie sind nicht derjenige, der mit den Konsequenzen Ihrer Entscheidungen fertig werden muss, ich muss. Und ich habe mich bereits mit den Konsequenzen einer ähnlichen Entscheidung Ihrer Vorgänger befasst, also habe ich Sie vorgewarnt, damit Sie nicht den gleichen Fehler machen.

Ich weiß, wie Software funktioniert, ich bin seit über 21 Jahren professioneller Softwareentwickler. Ich habe meinen ehrlichen Rat gegeben, nicht als Anfänger, sondern als kampferprobter Experte auf diesem speziellen Gebiet. Du kannst damit machen, was du willst, ich hoffe nur, du überlegst es dir gut, bevor du dir hier eine leichte Entscheidung triffst, denn die Konsequenzen sind weitreichend, und wie gesagt: mit denen müssen wir umgehen, nicht mit dir.

Auch ein Fehler kann später behoben werden, aber er ist noch nicht gemacht, ein guter Grund, es erst einmal nicht zu tun, oder?

Ihr Jungs überreagiert. Ich bezweifle, dass dies die gleichen Folgen haben würde wie das alte .NET.

Da coreclr in jeder Anwendung gebündelt ist, hat Legacy eine ganz andere Bedeutung. Es interessiert so ziemlich niemanden, ob Features von asp.net mvc 5 nicht auf mvc 4 oder 3 zurückportiert werden. Legacy hier wird eine andere Bedeutung haben, und die Geschichte anderer Projekte zeigt dies.

Gut, dass @terrajobst offen ist, dies für die nächsten Versionen zu berücksichtigen.

@nvivo Bitte versuchen Sie nicht, die Konsequenzen herunterzureden, mit denen _ich_ umgehen muss, da Sie sich nicht damit befassen müssen, aber ich tue es.

Danke @FransBouma, dass du mich in meine

Obwohl ich das Thema eröffnet habe, hat es keinerlei Auswirkungen auf meine Arbeit oder die Dinge, die mir wichtig sind. Ich dachte nur an die armen Entwickler wie Sie, die die ganze harte Arbeit auf dem Planeten leisten.

Ich bin wirklich froh, dass Leute wie Sie hier sind, um sich um die schwierigen Probleme zu kümmern. Bitte zögern Sie nicht, uns immer wieder (und immer wieder) zu sagen, um wie viel wichtigere Themen _Sie_ sich zu beschäftigen haben.

Danke @FransBouma.

_seufz_ Wo soll ich das alles sagen? Ich sage nur, bitte spiele die Dinge nicht herunter, da du das mit 'du überreagierst' machst, denke ich nicht, dass ich überreagiere. Mit 'mit denen muss man sich nicht auseinandersetzen' meine ich: die Folgen für _mich_. Weil ich weiß, was das ist, reagiere ich so, wie ich es getan habe. Offenbar ist das "überreagiert".

Aber egal.

Hier und hier haben wir Antworten auf dieses Problem.

Die offizielle Antwort lautet: Schnittstellen werden nicht in .NET Core 1.0 verfügbar sein, und obwohl es unwahrscheinlich ist, werden sie möglicherweise für zukünftige Versionen in einer anderen Form als in .NET in Betracht gezogen.

Ich schließe dieses Thema, da die ursprüngliche Frage behandelt wurde.

@nvivo Danke, aber am besten überlassen Sie offizielle Antworten den Personen, die tatsächlich für das Projekt verantwortlich sind, die auch in der Lage sind, Probleme selbst zu schließen, sobald sie entschieden haben, dass sie gelöst sind.

@terrajobst Gibt es eine aktualisierte offizielle Antwort/Zeitleiste für die Schnittstellen? und wie kann man dieses Arbeitselement in Zukunft am besten nachverfolgen? Sollen wir eine neue Ausgabe eröffnen oder werden Sie hier weiterhin Updates bereitstellen?

Lassen wir das erstmal offen. Aus meiner Sicht lautete die Antwort nicht "Lass uns die Schnittstellen nicht offenlegen". Die Antwort lautete: "Lassen Sie uns einen Weg finden, sie verfügbar zu machen, aber denken wir darüber nach, was dies für die DataTable-Abhängigkeit bedeutet".

Tut mir leid, dass ich mich so spät melde. Nachdem wir verschiedene Optionen in unserem Team besprochen hatten, entschieden wir uns, die Schnittstellen mit einer leeren Klasse von DataTable zurückzubringen. Dies ist keine ideale Lösung, aber angesichts des Zeitrahmens von RTM wird dieser Ansatz sicherstellen, dass wir in Zukunft praktikable Optionen rund um DataTable/DataSet verfolgen können. Wir werden versuchen, die Schnittstellen für System.Data.Common von v1 RTM einzubringen; SqlClient implementiert die Schnittstellen von v1 nicht. Vielen Dank für Ihr Feedback und Ihre Geduld. Ihr Feedback ist ein wichtiger Bestandteil, um den Datenstapel zu einem tragfähigen Produkt zu machen.

@YoungGah thx für das Update, wenn die DataTable-Klassen nur leere Platzhalter sind, was erfordert so viel Zeit / Aufwand (dh sie zurückzuhalten), um von SqlClient v1 implementiert zu werden?

@mythz Der Aufwand besteht darin, die Schnittstellen im Basistyp zu implementieren / an vorhandene Methoden weiterzuleiten. Die Kosten sollten minimal sein, aber normalerweise zeigen sich Dinge :smile:

Wir haben die folgenden Schnittstellen zu .Net CoreFX in System.Data.Common hinzugefügt

IDataParameter
IDataParameterCollection
IDataReader
IDataRecord
IDbBefehl
IDbVerbindung
IDbDataParameter
IDbTransaktion

Dies geschah in der PR https://github.com/dotnet/corefx/pull/6359

@saurabh500 Tolles Zeug, thx!

:+1:

:+1:

Fantastisch; Gibt es einen Meilenstein dafür, Nuget zu treffen? rc3?

Am 25. Februar 2016 um 02:54 Uhr, Saurabh Singh [email protected]
schrieb:

Wir haben die folgenden Schnittstellen zu .Net CoreFX in System.Data.Common hinzugefügt

IDataParameter
IDataParameterCollection
IDataReader
IDataRecord
IDbBefehl
IDbVerbindung
IDbDataParameter
IDbTransaktion

Dies geschah in der PR dotnet/corefx#6359 https://github.com/dotnet/corefx/pull/6359


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/dotnet/corefx/issues/3480#issuecomment -188577701.

Grüße,

Marc

Wie in der PR erwähnt, müssen wir verstehen, warum es auf diesen Schnittstellen keine asynchronen Methoden gibt. Wie vorgeschlagen, ist dies im Grunde eine abgespeckte Version der ADO.NET 1.1-Schnittstellen, und ich denke nicht, dass die Idee nur die Kompatibilität mit altem Code sein sollte.

Die Schnittstellen sollten sich auf den aktuellen Zustand von ado.net konzentrieren, da asynchrone Methoden heute die Standardmethode für den Zugriff auf jede Datenbank sein sollten. Ohne echte Unterstützung für asynchrone Methoden sind diese Schnittstellen für moderne Entwickler nutzlos
Entwicklung.

Und selbst wenn man die asynchronen Methoden von .NET 4.5 einschließt, sollten auch einige zusätzliche Methoden wie DbTrabsaction.CommitAsync hinzugefügt werden.

Der Postgres-Anbieter hat seiner API einige zusätzliche Methoden wie CommitAsync hinzugefügt, die sehr nützlich und notwendig sind.

Die aktuellen Schnittstellen sind in Ordnung, so wie sie sind. Die Implikationen, sie zu ändern, sind einfach zu groß.

Das asynchrone Modell unterscheidet sich stark vom synchronen Modell, und wie Sie vielleicht wissen, sollten Sie das asynchrone Modell vollständig verwenden. Daher gibt es wirklich keinen Grund, für beide APIs die gleichen Schnittstellen zu verwenden. Erstellen Sie neue für die asynchrone API.

Wenn das .NET-Team eine modernere API bereitstellen möchte, warum nicht einfach eine neue API erstellen, die nicht ADO.NET heißt? Kein Vermächtnis, durch das behindert werden könnte, und keine Beschwerden von der Community. Passt das auch gut dazu, wie dnx verteilt wird? dh unabhängige Pakete.

:+1: bei den Schnittstellen, guter Kompromiss.

Ich denke nicht, dass die Idee nur die Kompatibilität mit altem Code sein sollte.

Das ist die _gesamte_ Idee hier. Ansonsten wären Basisklassen in Ordnung. Das ist eine Menge Portierungsschmerzen, die wir vermeiden wollen.

Ohne echte Unterstützung für asynchrone Methoden sind diese Schnittstellen für die moderne Entwicklung nutzlos.

Ich bin damit nicht einverstanden, aber ich bin nicht unbedingt mit einer asynchronen Version der Schnittstellen einverstanden (die heute niemand implementiert). Dies wäre eine neue Funktion. Wir können nicht rückwirkend Mitglieder zu bestehenden Schnittstellen hinzufügen, das macht einfach viel zu viele Dinge kaputt. Ein IDbReaderAsync oder so etwas zu haben, ist IMO nicht verrückt, aber es ist eine andere Diskussion.

Ich bin fest davon überzeugt, dass async Methoden _nicht_ in den Basisklassen sein sollten, wenn die Standardimplementierung ein Sync-Wrapper ist - das ist aktiv schlecht und verschwenderisch. Wenn es einen anderen Vorschlag gibt, dann soll es so sein, aber auch hier: Das sollte sowieso ein anderes Thema sein.

Ok, vielleicht habe ich mich hier falsch ausgedrückt oder war zu stark mit meinen Worten.

Ich bin für eine zusätzliche Schnittstelle für Async bei Bedarf. Was mir nicht gut tut, ist, etwas zu haben, das einen offiziellen Vertrag für ADO.NET definiert (das sind Schnittstellen), aber keine asynchronen Methoden darin enthalten.

Aber dann würden alternative Schnittstellen für asynchrone Methoden wahrscheinlich andere Probleme verursachen ...

Ich bin der festen Überzeugung, dass asynchrone Methoden nicht in den Basisklassen enthalten sein sollten, wenn die Standardimplementierung ein Sync-Wrapper ist - das ist aktiv schlecht und verschwenderisch.

Ich stimme zu, dies ist der Hauptgrund, warum sich die meisten Anbieter nicht die Mühe machen, eine echte asynchrone API zu implementieren. Aber eine Änderung würde viel mehr Code zerstören und wahrscheinlich viel mehr Lärm verursachen als das Entfernen von Schnittstellen, da die Basisklassen seit 2.0 die eigentliche API für Provider sind.

Das Aktualisieren einer Bibliothek, um keine der 1.1-Schnittstellen zu verwenden, würde fast keine Auswirkungen haben, verglichen mit dem Entfernen des gesamten asynchronen Codes, der in den letzten Jahren geschrieben wurde, das wäre katastrophal. Der Kompromiss besteht darin, beides zu haben. Jeder heute geschriebene Code sollte asynchrone APIs verwenden, daher macht es keinen Sinn, dies wegzulassen.

Jeder heute geschriebene Code sollte asynchrone APIs verwenden.

Ich möchte nicht zu hart verletzen, aber diese ideale Welt ist weit von der Realität entfernt. Async ist sehr weit verbreitet und ansteckend. Sie können sich einfach nicht nur auf asynchrone APIs in Bibliotheken verlassen und erwarten, dass ganze Anwendungen aus einer Laune heraus asynchrone Verbraucher sind (die auch eine _Tonne_ ihres Codes in asynchron ändern). Sync -> Async überall ist auch aus vielen Deadlock- und Effizienzgründen sehr schlecht. Es wird noch viele Jahre lang synchronen Code geschrieben geben.

Es besteht ein starker Bedarf für beide APIs. Der Punkt ist: Lassen Sie uns die aktuellen nicht entfernen oder ihre Anwesenheit für einen hypothetischen und noch nicht entworfenen neuen Satz verzögern. Wir können uns unabhängig um den zweiten/neuen Satz kümmern.

Das Aktualisieren einer Bibliothek, um keine der 1.1-Schnittstellen zu verwenden, würde fast keine Auswirkungen haben, verglichen mit dem Entfernen des gesamten asynchronen Codes, der in den letzten Jahren geschrieben wurde

Worauf beziehst du dich? Es gab keine asynchronen APIs für einen solchen Code. Wenn Sie sich auf solche APIs verlassen, basieren sie nicht auf einer Basisklasse oder einer Schnittstelle, sondern direkt auf einem Anbieter. Das wird dadurch nicht beeinflusst.

Jeder heute geschriebene Code sollte asynchrone APIs verwenden, daher macht es keinen Sinn, dies wegzulassen.

Viele Dinge wegzulassen macht keinen Sinn ... außer der Tatsache, dass wir alle durch Ressourcen (insbesondere Zeit) eingeschränkt sind. Ich glaube nicht, dass irgendjemand etwas _permanent_ ausgelassen hat. Nichts ist vom Tisch. Es ist einfach noch nicht angekommen. Ich würde ein weiteres Problem speziell für das Starten einer Spezifikation für asynchrone Schnittstellen für eine zukünftige Generation öffnen.

Worauf beziehst du dich? Es gab keine asynchronen APIs für einen solchen Code. Wenn Sie sich auf solche APIs verlassen, basieren sie nicht auf einer Basisklasse oder einer Schnittstelle, sondern direkt auf einem Anbieter. Das wird dadurch nicht beeinflusst.

.NET 4.5 führte asynchrone Methoden für die Anbieterbasisklassen ein. Dies war im Jahr 2012, also vor fast 4 Jahren, also seit einiger Zeit Teil der ADO.NET-Provider-API. Entity Framework 6 (veröffentlicht 2013) hängt von diesen asynchronen APIs für alle Anbieter ab.

Asynchrone Methoden sind bereits so lange Teil von ADO.NET, dass viele Leute schreien würden, wenn dies nicht in .NET Core enthalten wäre. Ich habe _Legacy-Code_, der asynchrone Methoden in ADO.NET verwendet.

Ich plädiere dafür, dass dies auch in der neuen Schnittstellen-API vorhanden sein sollte, da sie _bereits_ Teil von ADO.NET sind.

Wenn die Leute die asynchronen APIs verwenden möchten (und sollten), können sie dies bereits tun
das _vor dieser Änderung_ mit den Basistypen. Letztendlich die Anfrage
zur Unterstützung der Schnittstellen wurde aus Gründen der Abwärtskompatibilität gemacht;
Das Hinzufügen von Methoden zu einer Schnittstelle _bläst dies völlig aus dem Wasser_.
Das heißt, es ist eigentlich so gut wie möglich als _Erweiterungsmethoden_ und
Typprüfung gegen die abstrakten Basistypen, aber... ziemlich hässlich und nicht
den Schmerz wert IMO.

So; Kurzversion: Ich persönlich kann nicht hinter das Hinzufügen von Async zum
Schnittstellen, da dies das zerstört, wofür wir sie im ersten Moment wollten
Platz. Wenn Sie asynchron möchten: Sie müssen gegen die Basisklassen codieren oder verwenden
Tools, die diese Details für Sie beschönigen.

Ich plädiere dafür, dass dies auch in der neuen Schnittstellen-API vorhanden sein sollte, da sie bereits Teil von ADO.NET sind.

Sie missverstehen den Zweck dieser ADO.NET-Schnittstellen, nämlich die Kompatibilität mit vorhandenem Code aufrechtzuerhalten. Das sind keine _neuen_ Interfaces, das sind _existierende_ Interfaces. Wenn Sie auf die neueren APIs zugreifen möchten, verweisen Sie auf die konkreten Basistypen.

@nvivo Entschuldigung, ich *Async -Methoden - fehlt da etwas Bestimmtes? Ich denke, Sie argumentieren, dass sie in Schnittstellen gebündelt werden sollten ... ja, sicher, aber das ist ein anderes Thema, zu dem ich Sie ermutige, es zu öffnen.

Mir wäre es viel lieber, sie wären von Anfang an eine Schnittstelle, da die Basisimplementierungen, die erforderlich sind, damit der aktuelle Ansatz funktioniert (async over sync), schreckliche Kompromisse sind, damit der gesamte Ansatz funktioniert. Aber wir können auch nicht beides haben: Entweder bewegen sie sich zu Schnittstellen oder sie sind (wie im aktuellen Fall) vorhanden, um Brüche zu minimieren.

Ja, ich glaube, wir drehen uns hier im Kreis. Ich habe dies bereits erwähnt, ich denke nicht, dass Schnittstellen _nur_ hinzugefügt werden sollten, um die Portierung von Code zu unterstützen. Aus Kompatibilitätssicht sind die Basisklassen seit 2005 die offizielle API für ADO.NET, und das wird von den Anbietern implementiert. Alles, was einen IDbCommand oder eine IDbConnection verwendet, könnte leicht portiert werden (und sollte portiert werden), um Basisklassen mit einem Suchen/Ersetzen zu verwenden und hat keine Nachteile.

Ich weiß, dass Sie kein Fan von ifdefs sind, aber dies für eine neue Plattform zu unterstützen, wird sowieso nur ein Teil der Migration sein.

Ich stimme zu, dass dies die ganze Zeit über Schnittstellen hätte sein sollen, aber da sie es nicht waren, möchte ich, dass sich dieses Problem nicht wiederholt. Wenn Schnittstellen hinzugefügt werden, sollten sie zumindest die aktuelle API darstellen und nicht das, was sie vor einem Jahrzehnt waren. Asynchrone Methoden sind ein integraler Bestandteil der aktuellen API und das ist die Richtung, in die Microsoft seit geraumer Zeit geht. Es wäre immer noch quellkompatibel, nur vollständiger.

@mgravell

Wenn Benutzer die asynchronen APIs verwenden möchten (und sollten), können sie dies bereits _vor dieser Änderung_ tun, indem sie die Basistypen verwenden.

Es geht nicht darum, etwas tun zu können. Es geht um Architektur. Schnittstellen sind Verträge, .NET Core ist ein neues Framework, das diesen Vertrag zu einer neu gestalteten Version der API hinzufügt.

.NET Core sollte einer neuen API keinen offiziellen Vertrag hinzufügen, nur um wirklich alten Code zu migrieren, während die meisten anderen Dinge sowieso fehlen werden. Wenn dies ein Problem ist, suchen die Leute einfach nicht genug nach Gründen, die sie ohnehin brauchen, um ihren Code zu ändern.

Wenn das alles ist, was das Team tut, dann ist das in Ordnung. IMO ist es nur eine schlechte Wahl.

Alles, was einen IDbCommand oder eine IDbConnection verwendet, könnte leicht portiert werden (und sollte portiert werden), um Basisklassen mit einem Suchen/Ersetzen zu verwenden und hat keine Nachteile.

Falsch. Die Probleme wurden in diesem Thread mehrmals von mehreren Bibliotheksautoren diskutiert, deren Erfahrungen aus erster Hand davon betroffen sind.

Ich weiß, du bist kein Fan von ifdefs

Alle Lösungen, die von Endkunden die Verwendung von ifdefs erfordern, sind eine fehlerhafte Entwicklungserfahrung und ein Nichtstarter, dh es wird nie ein erfolgreiches Produkt geben, bei dem Kunden ihren Code mit #defs verunreinigen müssen, wenn Alternativen vorhanden sind.

Wenn Schnittstellen hinzugefügt werden, sollten diese mindestens die aktuelle API darstellen

Dies sind keine neuen Schnittstellen, sondern wiederhergestellte Schnittstellen. Die aktuellen und zukünftigen APIs sind die Basisklassen, nicht diese Schnittstellen. Hier sollte es kein Problem geben, Sie können vergessen, dass diese Schnittstellen existieren und die Basistypen genauso weiter verwenden, wie vor der Wiederherstellung dieser Schnittstellen.

Es wird kein neuer Wert mehr zu diesem Thread hinzugefügt. Die vorhandenen ADO.NET-Schnittstellen wurden wiederhergestellt, damit dieser Thread stillgelegt werden kann. Das einzige, was von diesem Thread benötigt wird, sind Aktualisierungen von DataTable und GetSchemaTable() , die sich auf die vorhandenen Schnittstellen beziehen. Wenn Sie Architekturänderungen vorschlagen oder neue Schnittstellen befürworten möchten, öffnen Sie eine neue Ausgabe - die verhindert, dass jeder in dieser Liste Spam erhält.

@mythz lass uns nicht zustimmen.

Wenn ich nur meine 2 Cent als weiterer ORM-Entwickler hinzufüge, sind abstrakte Klassen immer ein Code-Geruch, wenn sie nicht von einer Schnittstelle unterstützt werden. Ich würde gerne neue Schnittstellen sehen, die den abstrakten Klassen und Methodensignaturen entsprechen, die mit einer Schnittstellen-API mit minimalen Anforderungen überladen sind.

Daumen hoch an die Community fürs Sprechen.

abstrakte Klassen sind immer ein Code-Geruch, wenn sie nicht von einer Schnittstelle unterstützt werden

@psibernetic Können Sie mir helfen, diese Aussage zu verstehen? Was ist mit diesem Code-Geruch?

@psibernetic

Schnittstellen und abstrakte Klassen geben uns einen Vertrag, beide geben uns eine Abstraktion und eine gute Definition für die API. Schnittstellen sind am nützlichsten, wenn Klassen implementiert werden, die mehr als eine Schnittstelle implementieren könnten oder Unterklassen einer anderen Basisklasse sind (vorausgesetzt, dies ist ein sehr großer Vorteil dieser Basisklasse). Insbesondere in diesem Fall haben konkrete Klassen für Connection, Command usw. für bestimmte Provider eine starke IS A-Beziehung zu den abstrakten API-Definitionen. Ich kann mir wirklich kein Szenario vorstellen, in dem ein Entwickler einer Unterklasse eine konkrete Implementierung für IDbConnection oder IConnection hinzufügen muss. Das fast einzige Szenario werden neue Klassen sein, die nur für die abstrakte Klasse abgeleitet werden und die gleiche Definition auf einem Interface zu "duplizieren" ist mehr Arbeit (unnötig) für den API-Designer.

Sehen Sie einen spezifischen und konkreten Vorteil oder ein Szenario darin, zwei gleiche Abstraktionen zu haben? Wenn die Schnittstelle einen praktischen und echten Nutzen _über_ der abstrakten Klasse in diesem speziellen API-Design bietet?

Der einzige Vorteil, den ich mir für die Schnittstellen vorstellen kann, ist die Abwärtskompatibilität, die wir mit den alten benötigen, um weniger tatsächlich ausgeführten Code zu zerstören, der von diesen Schnittstellen abhängt. Wenn wir nicht die alten Schnittstellen hätten, bin ich mir ziemlich sicher, dass die abstrakten Klassen ausreichen.

@eocampo Sie haben Recht, dass die abstrakten Klassen wahrscheinlich "gut genug" Abstraktion und Verträge bieten. Ich versuche immer, sehr schmale Schnittstellen bereitzustellen, die Aktionen darstellen, die ausgeführt werden können, wie IAsyncCommand und dergleichen. Dadurch können meine Frameworks auf eine Weise eingebunden werden, die zur Entwurfszeit des Frameworks möglicherweise nicht berücksichtigt wurde, mit geringerer Wahrscheinlichkeit für schreckliche NotSupportedExceptions oder NotImplementedExceptions.

@davkean Der Code-Geruch ist, dass Sie in den meisten Fällen, wenn auch nicht in allen, von einem Implementierer verlangen, einen ganzen Basissatz an Funktionalität zu implementieren oder zu erben, der möglicherweise nicht relevant ist. Ich erinnere mich, dass ich IDataReader-Implementierungen gesehen habe, die stattdessen aus einem Cache oder im Speicher lesen. Ich bin mir nicht sicher, ob die abstrakte Klasse DbDataReader dies zulassen würde, aber der Name impliziert nein.

Das Best-Practice-Modell, das hauptsächlich in Dot Net verfolgt wurde, bestand darin, Schnittstellen zu exponieren und von Basisklassen zu erben, nicht wahr?

Das Best-Practice-Modell, das hauptsächlich in Dot Net verfolgt wurde, bestand darin, Schnittstellen zu exponieren und von Basisklassen zu erben, nicht wahr?

@psibernetic Nun, nicht immer. Zum Beispiel hat diese Empfehlung auf der MSDN-Site mehr als ein Jahrzehnt dort. Und diese Richtlinie ist zumindest ab .Net Framework 2.0 sehr verbreitet.

Dies ist auch eine gute Referenz für die Richtlinien für das Bibliotheksdesign in .Net aus den frühen Tagen:

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

Wie auch immer, ich denke, die harte Diskussion hier dreht sich jetzt um zwei Themen:

a) Die Schnittstellen dienen nur der Abwärtskompatibilität oder können wir "von vorne anfangen" (Code brechen), um ein saubereres Schnittstellen- und API-Design zu ermöglichen.
b) Wie viel können wir für ein modernes und sauberes Design auf Kosten der Nichtkompatibilität mit dem vollständigen .Net-Framework gehen? (Kompatibilität speziell zwischen .Net Core und Full Core beim Datenzugriff [nicht die niedrigste und obligatorische Kompatibilität])

Wenn wir aus meiner Sicht die abstrakten Basisklassen als primären und bevorzugten Vertrag haben, müssen die _Schnittstellen_ nur aus Kompatibilitätsgründen mit den alten übereinstimmen. Ich verstehe, dass @nvivo bereits erklärt hat, dass nach .Net 2.0 der offizielle Vertrag die abstrakten Basisklassen waren, daher _könnten_ wir denken, dass Schnittstellen das Kompatibilitätsproblem nicht lösen werden, aber @mythz und @mikeobrien hatten hier auch harte Daten über die Abhängigkeit von Anbietern bereitgestellt auf den 1.1-Schnittstellen.

Um aufhören zu spammen und die Themen hier zu diskutieren, müssen wir dieses lange Gespräch noch einmal lesen und ich weiß nicht, ob wir uns auf die LISTE der spezifischen Themen einigen können, die wir ansprechen, oder ob es eine gute Idee ist, zwei oder drei neue zu erstellen Fragen zu jedem spezifischen Thema. Ich bin eher der erste Vorschlag, weil es hier viele gute Punkte gibt. Ich habe keine gute Idee, wie wir all dies zusammenfassen und etwas Rauschen (sogar meins) beseitigen können.

Apropos Schnittstellen: Gibt es Pläne, Teile von System.Data endlich generisch zu machen? Es hat mich immer gestört, dass System.Data seine API nie wirklich über .NET 1.1 hinaus aktualisiert hat, so dass die Leute Hacks wie die .AsEnumerable()-Erweiterungsmethode verwenden müssen, um ein IEnumerable zu erhaltenaus einer DataTable. Warum wurden Sammlungen wie DataRowCollection nicht aktualisiert, um die generischen Schnittstellen zu implementieren, wenn alles andere im Framework dies tat, als 2.0 herauskam?

Wird es einen Stub System.Data mit Typumleitungen geben? Ich muss ODP.NET verwenden, aber jetzt kann ich nicht.

Erstellt dotnet/corefx#7874

@mgravell @ploeh "Rickasaurus" implizierte Typklassen waren am Horizont (zumindest für F#, nicht sicher über C# oder .NET im Allgemeinen https://news.ycombinator.com/threads?id=Rickasaurus). Wenn es der Fall ist, dass sie für alle .NET kommen, würde es das Problem lösen?

Ich bin kein Haskell-Experte, aber ich verstehe, dass sie es Ihnen ermöglichen würden, ein einfaches IDbConnection , IDbConnectionAsync und alle zukünftigen gemeinsam genutzten Schnittstellen nachträglich anzuschrauben, ohne die Quelle zu beschädigen oder Binärkompatibilität und ohne Drittanbieter zu zwingen, alles zu implementieren. Dies unter Beibehaltung der leichten Nachahmungsfähigkeit.

Ist das ein richtiges Verständnis? Wenn ja, besteht die Möglichkeit, dass diese Funktion wirklich zu .NET kommt?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

btecu picture btecu  ·  3Kommentare

chunseoklee picture chunseoklee  ·  3Kommentare

noahfalk picture noahfalk  ·  3Kommentare

nalywa picture nalywa  ·  3Kommentare

bencz picture bencz  ·  3Kommentare