diff --git a/Dapper.Data NET40/Dapper.Data NET40.csproj b/Dapper.Data NET40/Dapper.Data NET40.csproj index 1238831..80a3c7e 100644 --- a/Dapper.Data NET40/Dapper.Data NET40.csproj +++ b/Dapper.Data NET40/Dapper.Data NET40.csproj @@ -52,9 +52,9 @@ false - + False - packages\Dapper.1.27\lib\net40\Dapper.dll + ..\Dapper.Data NET45\packages\Dapper.1.29\lib\net40\Dapper.dll @@ -66,13 +66,16 @@ - + + + + diff --git a/Dapper.Data NET40/Data/CommandDefinitionHelper.cs b/Dapper.Data NET40/Data/CommandDefinitionHelper.cs deleted file mode 100644 index 8277667..0000000 --- a/Dapper.Data NET40/Data/CommandDefinitionHelper.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Dapper.Data -{ - //public static class CommandDefinitionHelper - //{ - // public static CommandDefinition CommandDefinition(this string query) - // { - // return new CommandDefinition(query); - // } - - // public static CommandDefinition AddParams(CommandDefinition commandDefinition, object parameters) - // { - // commandDefinition.Parameters = parameters; - // return commandDefinition; - // } - //} -} diff --git a/Dapper.Data NET40/Data/DbConnectionFactory.cs b/Dapper.Data NET40/Data/DbConnectionFactory.cs index 5157288..87dc5b8 100644 --- a/Dapper.Data NET40/Data/DbConnectionFactory.cs +++ b/Dapper.Data NET40/Data/DbConnectionFactory.cs @@ -62,8 +62,7 @@ internal static IDbConnection CreateConnection(this DbProviderFactory sender, st /// internal static IDbConnection CreateOpenedConnection(this DbProviderFactory sender, string connectionString) { - var connection = sender.CreateConnection(); - connection.ConnectionString = connectionString; + var connection = sender.CreateConnection(connectionString); connection.Open(); return connection; } diff --git a/Dapper.Data NET40/Data/DbContext.cs b/Dapper.Data NET40/Data/DbContext.cs index 81a61b1..596f260 100644 --- a/Dapper.Data NET40/Data/DbContext.cs +++ b/Dapper.Data NET40/Data/DbContext.cs @@ -1,9 +1,12 @@ using System; using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; using System.Linq; using System.Text; using System.Data.Common; using System.Data; +using Dapper.Data.Generic; namespace Dapper.Data { @@ -38,19 +41,11 @@ IEnumerable Query( int? commandTimeout = 0 ); } - /// - /// Default behavior exposed by DbContext helps with injection - /// - public interface IDbContext : IDbCommand - { - void Batch(Action action); - TResult Batch(Func func); - } /// /// Interface to help with transaction managment /// - public interface ISession : IDbCommand + public interface ISession : IDbCommand, IDisposable { void BeginTransaction(); void BeginTransaction(IsolationLevel il); @@ -73,192 +68,175 @@ public interface ISession : IDbCommand } /// - /// Light weight DbContext implementation based on dapper - /// Use it to create your own DbContext - /// It will help manage connection life time and transactions + /// Default behavior exposed by DbContext helps with injection /// - public abstract class DbContext : IDbContext + public interface IDbContext : IDbContext + { } + + + /// + /// Default Session implementation + /// + class Session : ISession { - protected DbContext(string connectionName) - : this(new DbConnectionFactory(connectionName)) - {} + IDbConnection _connection; + IDbTransaction _transaction; - protected DbContext(IDbConnectionFactory connectionFactory) + public Session(IDbConnectionFactory connectionFactory) + : this(connectionFactory.CreateAndOpen()) + { } + + private Session(IDbConnection connection) { - ConnectionFactory = connectionFactory; + _connection = connection; + _transaction = null; } - public virtual IDbConnectionFactory ConnectionFactory + public void BeginTransaction() { - get; - private set; + if (_transaction == null) + { _transaction = _connection.BeginTransaction(); } } - /// - /// Enables execution of multiple statements and helps with - /// transaction management - /// - public virtual void Batch(Action action) + public void BeginTransaction(IsolationLevel il) { - using (var con = ConnectionFactory.CreateAndOpen()) - { - try - { - action(new Session(con)); - } - finally - { - con.Close(); - } - } + if (_transaction == null) + { _transaction = _connection.BeginTransaction(il); } } - /// - /// Enables execution of multiple statements and helps with - /// transaction management - /// - public virtual TResult Batch(Func func) + public void CommitTransaction() { - using (var con = ConnectionFactory.CreateAndOpen()) + if (_transaction != null) { - try - { - return func(new Session(con)); - } - finally - { - con.Close(); - } + _transaction.Commit(); } + _transaction = null; } - class Session : ISession + public void RollbackTransaction() { - readonly IDbConnection _connection; - IDbTransaction _transaction; - - public Session(IDbConnection connection) + if (_transaction != null) { - _connection = connection; - _transaction = null; + _transaction.Rollback(); } + _transaction = null; + } - public void BeginTransaction() - { - if (_transaction == null) - { _transaction = _connection.BeginTransaction(); } - } + public IDbConnection Connection { get { return _connection; } } - public void BeginTransaction(IsolationLevel il) - { - if (_transaction == null) - { _transaction = _connection.BeginTransaction(il); } - } + public int Execute(CommandDefinition command) + { + return _connection.Execute(command); + } - public void CommitTransaction() - { - if (_transaction != null) - { - _transaction.Commit(); - } - _transaction = null; - } + public IEnumerable Query(CommandDefinition command) + { + return _connection.Query(command); + } - public void RollbackTransaction() - { - if (_transaction != null) - { - _transaction.Rollback(); - } - _transaction = null; - } + public IEnumerable Query(string sql, Func map, object param = null, bool buffered = true, string splitOn = "Id", CommandType? commandType = null, int? commandTimeout = 0) + { + return _connection.Query(sql, map, param, _transaction, buffered, splitOn, commandTimeout, commandType); + } - public IDbConnection Connection { get { return _connection; } } + public IEnumerable Query(string sql, Func map, object param = null, bool buffered = true, string splitOn = "Id", CommandType? commandType = null, int? commandTimeout = 0) + { + return _connection.Query(sql, map, param, _transaction, buffered, splitOn, commandTimeout, commandType); + } - public int Execute(CommandDefinition command) - { - return _connection.Execute(command); - } + public IEnumerable Query(string sql, Func map, object param = null, bool buffered = true, string splitOn = "Id", CommandType? commandType = null, int? commandTimeout = 0) + { + return _connection.Query(sql, map, param, _transaction, buffered, splitOn, commandTimeout, commandType); + } - public IEnumerable Query(Dapper.CommandDefinition command) - { - return _connection.Query(command); - } + public IEnumerable Query(string sql, Func map, object param = null, bool buffered = true, string splitOn = "Id", CommandType? commandType = null, int? commandTimeout = 0) + { + return _connection.Query(sql, map, param, _transaction, buffered, splitOn, commandTimeout, commandType); + } - public IEnumerable Query(string sql, Func map, object param = null, bool buffered = true, string splitOn = "Id", CommandType? commandType = null, int? commandTimeout = 0) - { - return _connection.Query(sql, map, param, _transaction, buffered, splitOn, commandTimeout, commandType); - } + public int Execute(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return _connection.Execute(sql, param, _transaction, commandTimeout, commandType); + } - public IEnumerable Query(string sql, Func map, object param = null, bool buffered = true, string splitOn = "Id", CommandType? commandType = null, int? commandTimeout = 0) - { - return _connection.Query(sql, map, param, _transaction, buffered, splitOn, commandTimeout, commandType); - } + public IEnumerable Query(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return typeof(T) == typeof(IDictionary) ? _connection.Query(sql, param, _transaction, true, commandTimeout, commandType).OfType() : _connection.Query(sql, param, _transaction, true, commandTimeout, commandType); + } - public IEnumerable Query(string sql, Func map, object param = null, bool buffered = true, string splitOn = "Id", CommandType? commandType = null, int? commandTimeout = 0) - { - return _connection.Query(sql, map, param, _transaction, buffered, splitOn, commandTimeout, commandType); - } + public IEnumerable Query(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return _connection.Query(sql, param, null, true, commandTimeout, commandType); + } - public IEnumerable Query(string sql, Func map, object param = null, bool buffered = true, string splitOn = "Id", CommandType? commandType = null, int? commandTimeout = 0) - { - return _connection.Query(sql, map, param, _transaction, buffered, splitOn, commandTimeout, commandType); - } + public IEnumerable Query(Type type, string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return _connection.Query(type, sql, param, _transaction, true, commandTimeout, commandType); + } - public int Execute(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) - { - return _connection.Execute(sql, param, _transaction, commandTimeout, commandType); - } + public SqlMapper.GridReader QueryMultiple(CommandDefinition command) + { + return _connection.QueryMultiple(command); + } - public IEnumerable Query(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) - { - if (typeof(T) == typeof(IDictionary)) - { - return _connection.Query(sql, param, _transaction, true, commandTimeout, commandType).OfType(); - } - return _connection.Query(sql, param, _transaction, true, commandTimeout, commandType); - } + public SqlMapper.GridReader QueryMultiple(string sql, dynamic param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return _connection.QueryMultiple(new CommandDefinition(sql, param, _transaction, commandTimeout, commandType)); + } - public IEnumerable Query(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) - { - return _connection.Query(sql, param, null, true, commandTimeout, commandType); - } + [EditorBrowsable(EditorBrowsableState.Never)] + void IDisposable.Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } - public IEnumerable Query(Type type, string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + protected virtual void Dispose(bool disposing) + { + if (!disposing) + return; + try { - return _connection.Query(type, sql, param, _transaction, true, commandTimeout, commandType); + if (_transaction == null) + { return; } + _transaction.Rollback(); + _transaction.Dispose(); + _transaction = null; } - - public Dapper.SqlMapper.GridReader QueryMultiple(Dapper.CommandDefinition command) + catch (Exception ex) { - return _connection.QueryMultiple(command); + Trace.TraceError(ex.ToString()); } - - public Dapper.SqlMapper.GridReader QueryMultiple(string sql, dynamic param = null, System.Data.CommandType? commandType = null, int? commandTimeout = 0) + finally { - return _connection.QueryMultiple(new CommandDefinition(sql, param, _transaction, commandTimeout, commandType)); + if (_connection != null) + { + _connection.Close(); + _connection.Dispose(); + _connection = null; + } } - - } - - public int Execute(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) - { - return Batch(s => s.Execute(sql, param, commandType, commandTimeout)); } + } - public IEnumerable Query(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) - { - return Batch(s => s.Query(sql, param, commandType, commandTimeout)); - } + /// + /// Light weight DbContext implementation based on dapper + /// Use it to create your own DbContext + /// It will help manage connection life time and transactions + /// + public abstract class DbContext : DbContext, IDbContext + { + protected DbContext(string connectionName) + : base(connectionName) + { } - public IEnumerable Query(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) - { - return Batch(s => s.Query(sql, param, commandType, commandTimeout)); - } + protected DbContext(IDbConnectionFactory connectionFactory) + : base(connectionFactory) + { } - public IEnumerable Query(Type type, string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + protected override ISession CreateSession() { - return Batch(s => s.Query(type, sql, param, commandType, commandTimeout)); + return new Session(ConnectionFactory); } } } diff --git a/Dapper.Data NET40/Data/Generic/DbContext.cs b/Dapper.Data NET40/Data/Generic/DbContext.cs new file mode 100644 index 0000000..649a915 --- /dev/null +++ b/Dapper.Data NET40/Data/Generic/DbContext.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.Common; +using System.Diagnostics; +using System.Linq; +using System.Text; + +namespace Dapper.Data.Generic +{ + /// + /// Default behavior exposed by DbContext helps with injection + /// + public interface IDbContext : IDbCommand where TSession : ISession, IDisposable + { + void Batch(Action action); + TResult Batch(Func func); + } + + public abstract class DbContext : IDbContext where TSession : ISession, IDisposable + { + protected DbContext(string connectionName) + : this(new DbConnectionFactory(connectionName)) + { } + + protected DbContext(IDbConnectionFactory connectionFactory) + { + ConnectionFactory = connectionFactory; + } + + public virtual IDbConnectionFactory ConnectionFactory + { + get; + private set; + } + + /// + /// Enables execution of multiple statements and helps with + /// transaction management + /// + public void Batch(Action body) + { + using (var ctx = CreateSession()) + { + body(ctx); + } + } + + /// + /// Enables execution of multiple statements and helps with + /// transaction management + /// + public TResult Batch(Func body) + { + using(var ctx = CreateSession()) + { + return body(ctx); + } + } + + public int Execute(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return Batch(s => s.Execute(sql, param, commandType, commandTimeout)); + } + + public IEnumerable Query(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return Batch(s => s.Query(sql, param, commandType, commandTimeout)); + } + + public IEnumerable Query(string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return Batch(s => s.Query(sql, param, commandType, commandTimeout)); + } + + public IEnumerable Query(Type type, string sql, object param = null, CommandType? commandType = null, int? commandTimeout = 0) + { + return Batch(s => s.Query(type, sql, param, commandType, commandTimeout)); + } + + protected abstract TSession CreateSession(); + } +} diff --git a/Dapper.Data NET40/Data/Generic/Services/DbService.cs b/Dapper.Data NET40/Data/Generic/Services/DbService.cs new file mode 100644 index 0000000..f9d0fb5 --- /dev/null +++ b/Dapper.Data NET40/Data/Generic/Services/DbService.cs @@ -0,0 +1,21 @@ + +using System; +using Dapper.Data.Generic; +using Dapper.Data.Service; + +namespace Dapper.Data.Generic.Service +{ + public interface IDbService : IDbService where TSession : ISession + { + IDbContext Db { get; } + } + + public abstract class DbService: IDbService where TSession : ISession + { + public IDbContext Db + { get; private set; } + + protected DbService(IDbContext db) + { Db = db; } + } +} diff --git a/Dapper.Data NET40/Data/Generic/Services/DbServiceProvider.cs b/Dapper.Data NET40/Data/Generic/Services/DbServiceProvider.cs new file mode 100644 index 0000000..ddadb91 --- /dev/null +++ b/Dapper.Data NET40/Data/Generic/Services/DbServiceProvider.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Concurrent; +using System.Data.Common; +using Dapper.Data.Service; + +namespace Dapper.Data.Generic.Service +{ + public interface IDbServiceProvider : IServiceProvider, IDbContext where TSession : ISession + { + T GetService() where T : IDbService; + + Func, IDbService> GetServiceConstructor(); + } + + /// + /// Work in progress + /// I have used old style dataset and templates [DatasetTransformer.tt] to create Poco classes + /// I would like to update it to read queries from it and build them in to services where + /// each table in dataset will reperesent a service and queries defined in it will represent + /// actions that can be performed by the service + /// Heavy usage of iterfaces enable me to use injection and substitution. + /// + public abstract class DbServiceProvider : DbContext, IDbServiceProvider where TSession : ISession + { + private readonly ConcurrentDictionary, IDbService>> _services + = new ConcurrentDictionary, IDbService>>(); + + protected DbServiceProvider(string connectionName) + : base(connectionName) + { } + + protected DbServiceProvider(IDbConnectionFactory connectionFactory) + : base(connectionFactory) + { } + + /// + /// registeres new service + /// + [Obsolete("Please use RegisterService that excepts service constructor delegate")] + protected void RegisterService(Type constract, T service) where T : IDbService + { + RegisterService(constract, ctx => service); + } + + /// + /// registeres new service + /// + protected void RegisterService(Type constract, Func, IDbService> constructor) + { + _services[constract] = constructor; + } + + /// + /// used to retreave the service instance + /// + public T GetService() where T : IDbService + { + return (T)GetService(typeof(T)); + } + + object IServiceProvider.GetService(Type serviceType) + { + return GetService(serviceType); + } + + protected object GetService(Type serviceType) + { + return GetService(serviceType, this); + } + + private object GetService(Type serviceType, IDbServiceProvider context) + { + return GetServiceConstructor(serviceType)(context); + } + + public Func, IDbService> GetServiceConstructor() + { + return GetServiceConstructor(typeof(T)); + } + + protected Func, IDbService> GetServiceConstructor(Type serviceType) + { + return _services[serviceType]; + } + } +} \ No newline at end of file diff --git a/Dapper.Data NET40/Data/Service/DbService.cs b/Dapper.Data NET40/Data/Service/DbService.cs index fb84568..5e3039a 100644 --- a/Dapper.Data NET40/Data/Service/DbService.cs +++ b/Dapper.Data NET40/Data/Service/DbService.cs @@ -1,19 +1,20 @@  using System; +using Dapper.Data.Generic.Service; namespace Dapper.Data.Service { public interface IDbService { - IDbContext Db { get; } } public abstract class DbService : IDbService { - public IDbContext Db - { get; private set; } + protected DbService(IDbServiceProvider db) + { + Db = db; + } - protected DbService(IDbContext db) - { Db = db; } + protected IDbServiceProvider Db { get; private set; } } } diff --git a/Dapper.Data NET40/Data/Service/DbServiceProvider.cs b/Dapper.Data NET40/Data/Service/DbServiceProvider.cs index f3d2337..985633d 100644 --- a/Dapper.Data NET40/Data/Service/DbServiceProvider.cs +++ b/Dapper.Data NET40/Data/Service/DbServiceProvider.cs @@ -1,14 +1,17 @@ using System; using System.Collections.Concurrent; using System.Data.Common; +using Dapper.Data.Generic; +using Dapper.Data.Generic.Service; namespace Dapper.Data.Service { - public interface IDbServiceProvider: IServiceProvider + public interface IDbServiceProviderSession : ISession, IDbServiceProvider + { + } + + public interface IDbServiceProvider : IDbServiceProvider { - [Obsolete("Please use GetService instead")] - T For() where T : IDbService; - T GetService() where T : IDbService; } /// @@ -19,52 +22,61 @@ public interface IDbServiceProvider: IServiceProvider /// actions that can be performed by the service /// Heavy usage of iterfaces enable me to use injection and substitution. /// - public abstract class DbServiceProvider : DbContext, IDbServiceProvider + public class DbServiceProvider : DbServiceProvider { - private readonly ConcurrentDictionary _services - = new ConcurrentDictionary(); - - protected DbServiceProvider(string connectionName) - : base(connectionName) + protected DbServiceProvider(string connectionName) : base(connectionName) { } - protected DbServiceProvider(IDbConnectionFactory connectionFactory) - : base(connectionFactory) + protected DbServiceProvider(IDbConnectionFactory connectionFactory) : base(connectionFactory) { } - /// - /// registeres new service - /// - protected void RegisterService(Type constract, T service) where T : IDbService + protected override IDbServiceProviderSession CreateSession() { - _services[constract] = service; + return new ServiceSession(this, ConnectionFactory); } - /// - /// use this to retreave the service - /// - [Obsolete("Please use GetService instead")] - public T For() where T : IDbService + + class ServiceSession : Session, IDbServiceProviderSession { - return GetService(); - } + private readonly IDbServiceProvider _serviceProvider; - /// - /// used to retreave the service instance - /// - public T GetService() where T : IDbService - { - return (T)GetService(typeof(T)); - } + public ServiceSession( + IDbServiceProvider serviceProvider, + IDbConnectionFactory connectionFactory + ) : base(connectionFactory) + { + _serviceProvider = serviceProvider; + } - object IServiceProvider.GetService(Type serviceType) - { - return GetService(serviceType); - } + public void Batch(Action body) + { + body(this); + } - private object GetService(Type serviceType) - { - return _services[serviceType]; + public TResult Batch(Func body) + { + return body(this); + } + + public void Dispose() + { + Dispose(true); + } + + public T GetService() where T : IDbService + { + return (T)GetServiceConstructor()(this); + } + + public object GetService(Type serviceType) + { + return _serviceProvider.GetService(serviceType); + } + + public Func, IDbService> GetServiceConstructor() + { + return _serviceProvider.GetServiceConstructor(); + } } } } \ No newline at end of file diff --git a/Dapper.Data NET40/Data/SqlServer/SqlDbContext.cs b/Dapper.Data NET40/Data/SqlServer/SqlDbContext.cs new file mode 100644 index 0000000..4457929 --- /dev/null +++ b/Dapper.Data NET40/Data/SqlServer/SqlDbContext.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; +using System.Text; + +namespace Dapper.Data.SqlClient +{ + class SqlDbContext : DbContext + { + public SqlDbContext(string serverName, string databaseName) + : base(new SqlConnectionFactory(serverName, databaseName)) + { } + + public SqlDbContext(string serverName, string databaseName, string userId, string password) + : base(new SqlConnectionFactory(serverName, databaseName, userId, password)) + { } + } +} diff --git a/Dapper.Data NET40/packages.config b/Dapper.Data NET40/packages.config index ba79d6e..a0f0ec3 100644 --- a/Dapper.Data NET40/packages.config +++ b/Dapper.Data NET40/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Dapper.Data NET45/Dapper.Data NET45.csproj b/Dapper.Data NET45/Dapper.Data NET45.csproj index 3aebf27..5d283e0 100644 --- a/Dapper.Data NET45/Dapper.Data NET45.csproj +++ b/Dapper.Data NET45/Dapper.Data NET45.csproj @@ -53,8 +53,9 @@ false - - packages\Dapper.1.27\lib\net45\Dapper.dll + + False + ..\..\..\Pzena\Finance\Compensation Website\packages\Dapper.1.29\lib\net45\Dapper.dll @@ -72,9 +73,6 @@ True DatasetTransformer.tt - - Data\CommandDefinitionHelper.cs - Data\ConnectionStringBuilder.cs @@ -87,6 +85,12 @@ Data\DbContext.cs + + Data\Generic\DbContext.cs + + + Data\Generic\Services\DbServiceProvider.cs + Data\Service\DbService.cs @@ -147,7 +151,7 @@ xcopy "$(TargetPath)" "$(SolutionDir)NuGet.Dapper.Data\lib\net45" /V /H /R /K /Y - +