Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add feature detection properties to DbProviderFactory #37872

Merged
merged 1 commit into from
May 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/System.Data.Common/ref/System.Data.Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2327,6 +2327,8 @@ public abstract partial class DbProviderFactory
{
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; }
Expand Down
47 changes: 47 additions & 0 deletions src/System.Data.Common/src/System/Data/Common/DbProviderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion src/System.Data.Common/tests/System.Data.Common.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down Expand Up @@ -124,4 +125,4 @@
<ItemGroup>
<EmbeddedResource Include="Resources\$(AssemblyName).rd.xml" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -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) {}
}
}
}