Commit 28f03c0f authored by Helgi Hafþórsson's avatar Helgi Hafþórsson
Browse files

Now implemented as .NET Standard 2.0. Major changes

parent 7c2b7245
......@@ -9,26 +9,21 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{871C6815-F7D
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{22873875-9BB7-423E-9B7B-E8565A69D525}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Marsonsoft.Database.Tests", "test\Marsonsoft.Database.Tests\Marsonsoft.Database.Tests.csproj", "{7D9B2CBD-DB01-4EE6-9743-68B0590D844D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "codeAnalysis", "codeAnalysis", "{F452B515-F5E6-4393-B7A1-07EF1308E75E}"
ProjectSection(SolutionItems) = preProject
codeAnalysis\MarsonsoftRecommended.ruleset = codeAnalysis\MarsonsoftRecommended.ruleset
EndProjectSection
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marsonsoft.Database.Tests", "test\Marsonsoft.Database.Tests\Marsonsoft.Database.Tests.csproj", "{7D9B2CBD-DB01-4EE6-9743-68B0590D844D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{ED35E57D-7432-4DFB-99E3-9EAFD4812242}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample1", "samples\Sample1\Sample1.csproj", "{83B95ECA-576D-44F1-9FDA-31E582D61187}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7CFD7249-5969-4F42-B072-8C8892B90BE2}"
ProjectSection(SolutionItems) = preProject
LICENSE.md = LICENSE.md
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample2", "samples\Sample2\Sample2.csproj", "{AA40D389-895A-481D-A924-06411DF667B3}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Marsonsoft.Database.NetFramework.Tests", "test\Marsonsoft.Database.NetFramework.Tests\Marsonsoft.Database.NetFramework.Tests.csproj", "{BC39A1EA-E449-4524-A674-F2112624147E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleNetCore", "samples\SampleNetCore\SampleNetCore.csproj", "{61A3F1BE-7873-4C1E-A06B-2C38C166BF57}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample3", "samples\Sample3\Sample3.csproj", "{EC5BDE99-C537-42DC-8DDB-D654471123A8}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleNetFramework", "samples\SampleNetFramework\SampleNetFramework.csproj", "{83B95ECA-576D-44F1-9FDA-31E582D61187}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
......@@ -44,18 +39,18 @@ Global
{7D9B2CBD-DB01-4EE6-9743-68B0590D844D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D9B2CBD-DB01-4EE6-9743-68B0590D844D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D9B2CBD-DB01-4EE6-9743-68B0590D844D}.Release|Any CPU.Build.0 = Release|Any CPU
{BC39A1EA-E449-4524-A674-F2112624147E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BC39A1EA-E449-4524-A674-F2112624147E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BC39A1EA-E449-4524-A674-F2112624147E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BC39A1EA-E449-4524-A674-F2112624147E}.Release|Any CPU.Build.0 = Release|Any CPU
{61A3F1BE-7873-4C1E-A06B-2C38C166BF57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61A3F1BE-7873-4C1E-A06B-2C38C166BF57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61A3F1BE-7873-4C1E-A06B-2C38C166BF57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61A3F1BE-7873-4C1E-A06B-2C38C166BF57}.Release|Any CPU.Build.0 = Release|Any CPU
{83B95ECA-576D-44F1-9FDA-31E582D61187}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{83B95ECA-576D-44F1-9FDA-31E582D61187}.Debug|Any CPU.Build.0 = Debug|Any CPU
{83B95ECA-576D-44F1-9FDA-31E582D61187}.Release|Any CPU.ActiveCfg = Release|Any CPU
{83B95ECA-576D-44F1-9FDA-31E582D61187}.Release|Any CPU.Build.0 = Release|Any CPU
{AA40D389-895A-481D-A924-06411DF667B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA40D389-895A-481D-A924-06411DF667B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA40D389-895A-481D-A924-06411DF667B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA40D389-895A-481D-A924-06411DF667B3}.Release|Any CPU.Build.0 = Release|Any CPU
{EC5BDE99-C537-42DC-8DDB-D654471123A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC5BDE99-C537-42DC-8DDB-D654471123A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC5BDE99-C537-42DC-8DDB-D654471123A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC5BDE99-C537-42DC-8DDB-D654471123A8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -63,9 +58,9 @@ Global
GlobalSection(NestedProjects) = preSolution
{5A8FB352-10B9-4EB2-9297-49C9A66A65CE} = {871C6815-F7D6-4747-8B65-F39063EF1DBF}
{7D9B2CBD-DB01-4EE6-9743-68B0590D844D} = {22873875-9BB7-423E-9B7B-E8565A69D525}
{BC39A1EA-E449-4524-A674-F2112624147E} = {22873875-9BB7-423E-9B7B-E8565A69D525}
{61A3F1BE-7873-4C1E-A06B-2C38C166BF57} = {ED35E57D-7432-4DFB-99E3-9EAFD4812242}
{83B95ECA-576D-44F1-9FDA-31E582D61187} = {ED35E57D-7432-4DFB-99E3-9EAFD4812242}
{AA40D389-895A-481D-A924-06411DF667B3} = {ED35E57D-7432-4DFB-99E3-9EAFD4812242}
{EC5BDE99-C537-42DC-8DDB-D654471123A8} = {ED35E57D-7432-4DFB-99E3-9EAFD4812242}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C1FECD20-9ABB-464F-A4FB-7AD5F68A9E27}
......
# Marsonsoft.Database [![Build status](https://ci.appveyor.com/api/projects/status/jws0dh79my9bp7rk?svg=true)](https://ci.appveyor.com/project/helgihaf/database) [![NuGet](https://badge.fury.io/nu/Marsonsoft.Database.svg)](https://www.nuget.org/packages/Marsonsoft.Database) [![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://en.wikipedia.org/wiki/MIT_License)
## About
This is a simple library that makes writing database provider agnostic code slightly more convenient.
This is a small library that can simplify your database code and make it more database provider agnostic.
## Database Provider Agnostic Code?
Instead of your code directly depending on libraries such as `Oracle.ManagedDataAccess.Client` you can reference the standard `System.Data` and decide at runtime which database provider you will be using.
## Simplify?
You don't have to
An IDataEnviroment is a database environment where all your choices have already been made: what connection string you use, the type of the database client you use and more. You can just grab an IDataEnvironment instance and start using connections and commands without worring about types or connection strings.
## Features
Today you can already write provider agnostic code without this library. The library adds the following features:
A DataEnvironmentProvider provides you with the IDataEnviroments. This is the place where the choices are made about connection strings and database clients (providers).
Use a DataEnvironmentProviderFactory
to create a DataEnvironmentProvider
to create an IDataEnvironment
to create an IDbConnection
to create an IDbCommand
## Background
Database provider agnostic code enables you to write code that communicates with a database without direct dependency on specific types of providers.
For example, you can write code that directly creates objects in the `Oracle.DataAccess.Client` namespace and that code will be directly dependent upon the Oracle.DataAccess.Client.dll.
Alternatively you can write your code agains the standard `System.Data` namespace and decide at runtime which database provider you will be using, be it Oracle.DataAccess.Client or the newer Oracle.ManagedDataAccess.Client.
But this is all possible without using this library. However, this library makes it a little bit easier to follow this path.
At the center of the library is an interface called `IDataEnvironment`. You create this environment by providing a connection string and a database provider factory. Using this interface you can:
* Create or open a database connection,
* Access the correct `System.Data.Common.DbProviderFactory` for your connection type,
* Access a minimal SQL statement factory for creating SQL statements suited for the connection type, and
* Validate SQL identifiers.
## Feature Overview
* Easy method of obtaining connection strings and provider from config file.
* Automatic creation of data provider based on config data.
* Easy to obtain correct connection type for either default connection string or a named connection string.
......@@ -15,79 +37,83 @@ Today you can already write provider agnostic code without this library. The lib
* Convenience methods for getting values from DbDataReader-s.
* Convenience methods to handle Oracle specific types (ref cursors).
* An ISqlFactory interface and classes that implemented it for dealing with different flavors of SQL.
* Builtin support for SQL Server, Oracle Managed, Oracle Native and MySql
* Easily extensible for other database providers.
## Code Examples
### Sample 1: The Simple Default
Packages needed:
```Powershell
Install-Package Marsonsoft.Database
Install-Package Oracle.ManagedDataAccess
```
## Code Example
(See samples/SampleNetCore)
Code:
```C#
using Marsonsoft.Database;
using Microsoft.Extensions.Configuration;
using System.Diagnostics;
using System.IO;
namespace Sample1
namespace SampleNetCore
{
class Program
{
static void Main(string[] args)
{
var dataEnvironment = DataEnvironmentProvider.Default.GetDefault();
using (var connection = dataEnvironment.ConnectionProvider.OpenConnection())
{
//...
}
}
}
}
```
// Build up a configuration from our json file
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appSettings.json", optional: true)
.Build();
The following snippet is required in app.config for Sample1 to work:
```xml
<connectionStrings>
<add name="DefaultConnection" providerName="Oracle.ManagedDataAccess.Client" connectionString="Data Source=myOracle;User Id=myUser;Password=myPass;" />
</connectionStrings>
```
By convention, the name of the default connection string is `DefaultConnection`. In this XML example the `providerName` is required because we don't specify a default provider invariant name.
#### Example 2: Named Connection String
// Get a DatabaseConfiguration from our configuration
var databaseConfiguration = configuration.Get<Marsonsoft.Database.Configuration.DatabaseConfiguration>();
Packages needed:
```Powershell
Install-Package Marsonsoft.Database
Install-Package MySql.Data
```
// Create a DataEnvironmentProvider for the DatabaseConfiguration
var dataEnvironmentProvider = DataEnvironmentProviderFactory.Create(databaseConfiguration);
```C#
using Marsonsoft.Database;
// Get the default IDataEnvironment for our configuration
var dataEnvironment = dataEnvironmentProvider.GetDefault();
namespace Sample2
{
class Program
{
static void Main(string[] args)
{
var dataEnvironment = DataEnvironmentProvider.Default.GetByConnectionStringName("OtherConnection");
// Start using the dataEnvironment
using (var connection = dataEnvironment.ConnectionProvider.OpenConnection())
{
//...
// Use the IDbConnection to create the IDbCommand
using (var command = connection.CreateCommand("select id, name from customers where type = :type"))
{
// Extension method to add a parameter
command.AddParameter("type", "good");
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
// Use extension methods to get typed + named values from the reader
Debug.WriteLine($"id: {reader.GetValue<long>("id")}, name: {reader.GetValue<string>("name")}");
}
}
}
}
}
}
}
```
The following snippet is required in app.config for Sample1 to work:
```xml
<connectionStrings>
<add name="OtherConnection" providerName="Oracle.ManagedDataAccess.Client" connectionString="Data Source=myDataSource;User Id=myUserId;Password=myPassword;"/>
</connectionStrings>
The appSettings.json file for this example:
```json
{
"defaultName": "defaultConnection",
"connections": [
{
"name": "defaultConnection",
"providerName": "System.Data.SqlClient",
"connectionString": "server=myServerAddress;database=myDataBase;user id=myUsername;password=myPassword"
}
],
"providers": [
{
"invariantName": "System.Data.SqlClient",
"assemblyQualifiedName": "System.Data.SqlClient.SqlClientFactory, System.Data.SqlClient, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
}
]
}
```
## License
A short snippet describing the license (MIT, Apache, etc.)
\ No newline at end of file
The project is licensed under the MIT license.
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Marsonsoft Recommended" Description="Based on the AllRules ruleset, excluding those deemed irrelvant." ToolsVersion="15.0">
<Include Path="allrules.ruleset" Action="Default" />
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CA1000" Action="None" />
<Rule Id="CA1006" Action="None" />
<Rule Id="CA1014" Action="None" />
<Rule Id="CA1020" Action="None" />
<Rule Id="CA1021" Action="None" />
<Rule Id="CA1062" Action="None" />
<Rule Id="CA1065" Action="None" />
<Rule Id="CA1303" Action="None" />
<Rule Id="CA1308" Action="None" />
<Rule Id="CA1704" Action="None" />
<Rule Id="CA1707" Action="None" />
<Rule Id="CA1709" Action="None" />
<Rule Id="CA1710" Action="None" />
<Rule Id="CA1720" Action="None" />
<Rule Id="CA1726" Action="None" />
<Rule Id="CA1810" Action="None" />
<Rule Id="CA2000" Action="None" />
<Rule Id="CA2103" Action="None" />
<Rule Id="CA2122" Action="None" />
<Rule Id="CA2204" Action="None" />
<Rule Id="CA2210" Action="None" />
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<Rule Id="SA1005" Action="None" />
<Rule Id="SA1101" Action="None" />
<Rule Id="SA1200" Action="None" />
<Rule Id="SA1311" Action="None" />
<Rule Id="SA1404" Action="None" />
<Rule Id="SA1501" Action="None" />
<Rule Id="SA1503" Action="None" />
<Rule Id="SA1518" Action="None" />
<Rule Id="SA1600" Action="None" />
<Rule Id="SA1633" Action="None" />
<Rule Id="SX1101" Action="Warning" />
</Rules>
</RuleSet>
\ No newline at end of file
using Marsonsoft.Database;
namespace Sample1
{
class Program
{
static void Main(string[] args)
{
//var dataEnvironment = DataEnvironmentProvider
// .Default.GetDefault();
//using (var connection = dataEnvironment.ConnectionProvider.OpenConnection())
//{
// //...
//}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="DefaultConnection" providerName="Oracle.ManagedDataAccess.Client" connectionString="Data Source=myOracle;User Id=myUser;Password=myPass;" />
<add name="OtherConnection" providerName="MySql.Data.MySqlClient" connectionString="Server=myServer;Database=myDatabase;Uid=myUid;Pwd=myPass;" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
</configuration>
\ No newline at end of file
using Marsonsoft.Database;
namespace Sample2
{
class Program
{
static void Main(string[] args)
{
//var dataEnvironment = DataEnvironmentProvider.Default.GetByConnectionStringName("OtherConnection");
//using (var connection = dataEnvironment.ConnectionProvider.OpenConnection())
//{
// //...
//}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MySql.Data" version="6.9.9" targetFramework="net462" />
</packages>
\ No newline at end of file
{
"connections": [
{
"name": "defaultConnection",
"providerName": "Oracle.ManagedDataAccess.Client",
"connectionString": "Data Source=myOracle;User Id=myUser;Password=myPass;"
}
],
"providers": [
{
"name": "Oracle.ManagedDataAccess.Client",
"type": "Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342"
}
]
}
......@@ -3,7 +3,7 @@ using Microsoft.Extensions.Configuration;
using System.Diagnostics;
using System.IO;
namespace Sample3
namespace SampleNetCore
{
class Program
{
......
......@@ -9,6 +9,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.4.0" />
</ItemGroup>
<ItemGroup>
......
{
"defaultName": "defaultConnection",
"connections": [
{
"name": "defaultConnection",
"providerName": "System.Data.SqlClient",
"connectionString": "server=myServerAddress;database=myDataBase;user id=myUsername;password=myPassword"
}
],
"providers": [
{
"invariantName": "System.Data.SqlClient",
"assemblyQualifiedName": "System.Data.SqlClient.SqlClientFactory, System.Data.SqlClient, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
}
]
}
using Marsonsoft.Database;
using System.Configuration;
using Marsonsoft.Database.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Data.Common;
using System.Data;
using System.Diagnostics;
namespace SampleNetFramework
{
class Program
{
static void Main(string[] args)
{
// Get a DatabaseConfiguration from app.config and existing .NET Framework conventions
var databaseConfiguration = GetDatabaseConfiguration();
// Create a DataEnvironmentProvider for the DatabaseConfiguration
var dataEnvironmentProvider = DataEnvironmentProviderFactory.Create(databaseConfiguration);
// Get the default IDataEnvironment for our configuration
var dataEnvironment = dataEnvironmentProvider.GetDefault();
// Start using the dataEnvironment
using (var connection = dataEnvironment.ConnectionProvider.OpenConnection())
{
// Use the IDbConnection to create the IDbCommand
using (var command = connection.CreateCommand("select id, name from customers where order_type = :order_type"))
{
// Extension method to add a parameter
command.AddParameter("order_type", "good");
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
// Use extension methods to get typed + named values from the reader
Debug.WriteLine($"id: {reader.GetValue<long>("id")}, name: {reader.GetValue<string>("name")}");
}
}
}
}
}
private static Marsonsoft.Database.Configuration.DatabaseConfiguration GetDatabaseConfiguration()
{
return new Marsonsoft.Database.Configuration.DatabaseConfiguration
{
DefaultName = ConfigurationManager.AppSettings["DefaultConnection"] ?? "DefaultConnection",
DefaultProviderName = ConfigurationManager.AppSettings["DefaultProvider"],
Connections = GetConnections(),
Providers = GetProviders()
};
}
private static List<Connection> GetConnections()
{
return ConfigurationManager.ConnectionStrings.Cast<ConnectionStringSettings>().Select(s => new Connection
{
Name = s.Name,
ProviderName = s.ProviderName,
ConnectionString = s.ConnectionString
}).ToList();
}
private static List<Provider> GetProviders()
{
return (
from row in DbProviderFactories.GetFactoryClasses().Rows.Cast<DataRow>()
select new Provider
{
InvariantName = row[2] as string,
AssemblyQualifiedName = row[3] as string
}).ToList();
}
}
}
......@@ -6,8 +6,8 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{83B95ECA-576D-44F1-9FDA-31E582D61187}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Sample1</RootNamespace>
<AssemblyName>Sample1</AssemblyName>
<RootNamespace>SampleNetFramework</RootNamespace>
<AssemblyName>SampleNetFramework</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
......@@ -36,12 +36,12 @@
<HintPath>..\..\packages\Oracle.ManagedDataAccess.12.2.1100\lib\net40\Oracle.ManagedDataAccess.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
......
using System;
using System.Collections.Generic;
using System.Text;
namespace Marsonsoft.Database.Configuration
namespace Marsonsoft.Database.Configuration
{
/// <summary>
/// Represents a single, named connection string.
......@@ -15,7 +11,7 @@ namespace Marsonsoft.Database.Configuration
public string Name { get; set; }
/// <summary>
/// Gets or sets the provider name.
/// Gets or sets the provider name. This is the same as <see cref="Provider.InvariantName"/>.
/// </summary>
public string ProviderName { get; set; }
......
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Generic;
namespace Marsonsoft.Database.Configuration
{
/// <summary>
/// Represents the configuration required to obtain an <see cref="IDataEnvironmentProvider"/> and ultimately an <see cref="IDataEnvironment"/>.
/// </summary>
public class DatabaseConfiguration
{
/// <summary>
/// Gets or sets the default connection strings' name. Required, cannot be null.
/// Gets or sets the default connection string name. Required, cannot be null.
/// </summary>
public string DefaultName { get; set; }
/// <summary>
/// Gets or sets the default provider name if specified, null if none is specified..
/// Gets or sets the default provider name if specified, null if none is specified.
/// </summary>
public string DefaultProviderName { get; set; }
......@@ -21,6 +22,9 @@ namespace Marsonsoft.Database.Configuration
/// </summary>
public List<Connection> Connections { get; set; }
/// <summary>
/// Gets or sets the provider list.
/// </summary>
public List<Provider> Providers { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Marsonsoft.Database.Configuration
namespace Marsonsoft.Database.Configuration
{
/// <summary>
/// Contains information about a provider that implements <see cref="System.Data.Common.DbProviderFactory"/>.
/// </summary>
public class Provider
{
public string Name { get; set; }
public string Type { get; set; }
/// <summary>
/// Name that can be used programmatically to refer to the data provider.
/// </summary>
public string InvariantName { get; set; }
/// <summary>
/// Fully qualified name of the factory class, which contains enough information to instantiate the object.
/// </summary>
public string AssemblyQualifiedName { get; set; }
}
}
......@@ -18,7 +18,7 @@ namespace Marsonsoft.Database
/// <summary>
/// Initializes a new instance of the <see cref="DataEnvironmentProvider"/> class.
/// </summary>
/// <param name="infoProvider">The information provider to use.</param>
/// <param name="configuration">The database configuration to use.</param>
/// <param name="dbProviderFactories">The DB provider factory factory to use.</param>
/// <exception cref="System.ArgumentNullException">infoProvider</exception>
protected internal DataEnvironmentProvider(Configuration.DatabaseConfiguration configuration, IDbProviderFactoryFactory dbProviderFactories)
......@@ -41,6 +41,10 @@ namespace Marsonsoft.Database
{
ValidateTypeToAdd(type);
var providerNames = GetAllProviderNamesSupportedBy(type);
if (!providerNames.Any())
{
throw new ArgumentException($"Type {type.FullName} has no {nameof(ProviderSupportAttribute)}", nameof(type));
}</