Add feature detection properties to DbProviderFactory
authorShay Rojansky <roji@roji.org>
Thu, 30 May 2019 10:50:02 +0000 (12:50 +0200)
committerShay Rojansky <roji@roji.org>
Thu, 30 May 2019 12:09:08 +0000 (14:09 +0200)
CanCreateDataAdapter, CanCreateCommandBuilder

Closes dotnet/corefx#35564

Commit migrated from https://github.com/dotnet/corefx/commit/60d65afa0160a0b27e8df6b8f450ead8ab7f4214

src/libraries/System.Data.Common/ref/System.Data.Common.cs
src/libraries/System.Data.Common/src/System/Data/Common/DbProviderFactory.cs
src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj
src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.netcoreapp.cs [new file with mode: 0644]

index c9c2083..617af05 100644 (file)
@@ -2337,6 +2337,8 @@ namespace System.Data.Common
     {
         protected DbProviderFactory() { }
         public virtual bool CanCreateDataSourceEnumerator { get { throw null; } }
+        public virtual bool CanCreateDataAdapter { get { throw null; } }
+        public virtual bool CanCreateCommandBuilder { get { throw null; } }
         public virtual System.Data.Common.DbCommand CreateCommand() { throw null; }
         public virtual System.Data.Common.DbCommandBuilder CreateCommandBuilder() { throw null; }
         public virtual System.Data.Common.DbConnection CreateConnection() { throw null; }
index 0e568d7..61f7e5c 100644 (file)
@@ -6,10 +6,57 @@ namespace System.Data.Common
 {
     public abstract partial class DbProviderFactory
     {
+        private bool? _canCreateDataAdapter;
+        private bool? _canCreateCommandBuilder;
+
         protected DbProviderFactory() { }
 
         public virtual bool CanCreateDataSourceEnumerator => false;
 
+        public virtual bool CanCreateDataAdapter
+        {
+            get
+            {
+                if (!_canCreateDataAdapter.HasValue)
+                {
+                    var adapter = CreateDataAdapter();
+                    if (adapter == null)
+                    {
+                        _canCreateDataAdapter = false;
+                    }
+                    else
+                    {
+                        _canCreateDataAdapter = true;
+                        adapter.Dispose();
+                    }
+                }
+
+                return _canCreateDataAdapter.Value;
+            }
+        }
+
+        public virtual bool CanCreateCommandBuilder
+        {
+            get
+            {
+                if (!_canCreateCommandBuilder.HasValue)
+                {
+                    var builder = CreateCommandBuilder();
+                    if (builder == null)
+                    {
+                        _canCreateCommandBuilder = false;
+                    }
+                    else
+                    {
+                        _canCreateCommandBuilder = true;
+                        builder.Dispose();
+                    }
+                }
+
+                return _canCreateCommandBuilder.Value;
+            }
+        }
+
         public virtual DbCommand CreateCommand() => null;
 
         public virtual DbCommandBuilder CreateCommandBuilder() => null;
index 7642909..2448dea 100644 (file)
@@ -21,6 +21,7 @@
     <Compile Include="System\Data\Common\DbDataAdapterTest.cs" />
     <Compile Include="System\Data\Common\DbDataReaderMock.cs" />
     <Compile Include="System\Data\Common\DbDataReaderTest.cs" />
+    <Compile Include="System\Data\Common\DbProviderFactoryTest.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="System\Data\Common\DbTransactionTest.cs" />
     <Compile Include="System\Data\Common\RowUpdatedEventArgsTest.cs" />
     <Compile Include="System\Data\Common\RowUpdatingEventArgsTest.cs" />
   <ItemGroup>
     <EmbeddedResource Include="Resources\$(AssemblyName).rd.xml" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.netcoreapp.cs b/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.netcoreapp.cs
new file mode 100644 (file)
index 0000000..9a2b138
--- /dev/null
@@ -0,0 +1,51 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+using System.Data.Common;
+
+namespace System.Data.Tests.Common
+{
+    public class DbProviderFactoryTest
+    {
+        [Fact]
+        public void CanCreateDataAdapter()
+        {
+            Assert.True(ProviderFactoryWithExtras.Instance.CanCreateDataAdapter);
+            Assert.False(ProviderFactoryWithoutExtras.Instance.CanCreateDataAdapter);
+        }
+
+        [Fact]
+        public void CanCreateCommandBuilder()
+        {
+            Assert.True(ProviderFactoryWithExtras.Instance.CanCreateCommandBuilder);
+            Assert.False(ProviderFactoryWithoutExtras.Instance.CanCreateCommandBuilder);
+        }
+
+        public sealed class ProviderFactoryWithExtras : DbProviderFactory
+        {
+            public static readonly ProviderFactoryWithExtras Instance = new ProviderFactoryWithExtras();
+            private ProviderFactoryWithExtras() { }
+
+            public override DbDataAdapter CreateDataAdapter() => new MyAdapter();
+            public override DbCommandBuilder CreateCommandBuilder() => new MyCommandBuilder();
+        }
+
+        public sealed class ProviderFactoryWithoutExtras : DbProviderFactory
+        {
+            public static readonly ProviderFactoryWithoutExtras Instance = new ProviderFactoryWithoutExtras();
+            private ProviderFactoryWithoutExtras() { }
+        }
+
+        private class MyAdapter : DbDataAdapter {}
+
+        private class MyCommandBuilder : DbCommandBuilder
+        {
+            protected override string GetParameterPlaceholder(int parameterOrdinal) => null;
+            protected override string GetParameterName(string parameterName) => null;
+            protected override string GetParameterName(int parameterOrdinal) => null;
+            protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause) {}
+            protected override void SetRowUpdatingHandler(DbDataAdapter adapter) {}
+        }
+    }
+}