From 1117bfc5b115cb2f6eda0df14c0483d27b621cd1 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 30 May 2019 12:50:02 +0200 Subject: [PATCH] Add feature detection properties to DbProviderFactory CanCreateDataAdapter, CanCreateCommandBuilder Closes dotnet/corefx#35564 Commit migrated from https://github.com/dotnet/corefx/commit/60d65afa0160a0b27e8df6b8f450ead8ab7f4214 --- .../System.Data.Common/ref/System.Data.Common.cs | 2 + .../src/System/Data/Common/DbProviderFactory.cs | 47 ++++++++++++++++++++ .../tests/System.Data.Common.Tests.csproj | 3 +- .../Common/DbProviderFactoryTest.netcoreapp.cs | 51 ++++++++++++++++++++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.netcoreapp.cs diff --git a/src/libraries/System.Data.Common/ref/System.Data.Common.cs b/src/libraries/System.Data.Common/ref/System.Data.Common.cs index c9c2083..617af05 100644 --- a/src/libraries/System.Data.Common/ref/System.Data.Common.cs +++ b/src/libraries/System.Data.Common/ref/System.Data.Common.cs @@ -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; } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbProviderFactory.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbProviderFactory.cs index 0e568d7..61f7e5c 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbProviderFactory.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbProviderFactory.cs @@ -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; diff --git a/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj b/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj index 7642909..2448dea 100644 --- a/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj +++ b/src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj @@ -21,6 +21,7 @@ + @@ -124,4 +125,4 @@ - \ No newline at end of file + 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 index 0000000..9a2b138 --- /dev/null +++ b/src/libraries/System.Data.Common/tests/System/Data/Common/DbProviderFactoryTest.netcoreapp.cs @@ -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) {} + } + } +} -- 2.7.4