Thursday, 29 October 2020

who owns the IPR?

Who owns IPR?

Easy answer, at least that what I though.  Well after a lot of research it seem that it isn't as cut and dry as it may first appear.

It all appears to heavily depend on two things, your contract and you employment definition.

For example, if you are employed as a cleaner and in passing you notice that the chairs used by software engineer could be improved by adding a bin to the arm of the chair.  You then go and build a prototype,  which the company then uses, pays for 1,000 of them to be built.  The cleaner is given a pat on the back and a new mop.  It would be easy to assume, he's working and employed by the company,  so the IPR belongs to the company.   And you would be wrong.  In all instances of creating something the IPR belongs to the individual who created it.  If employed, then the IPR transfers automatically only if the individual was employed specifically to design chairs, or there was a clause in the contract which states anything you develop whilst in employed belongs to the company.  

So the second part gets the company out of jail.  Yes and no.  If the cleaner had developed a new type of mop, then yes.  However,  the chair has nothing at all to do with his job.  His employment contract states he was employed as a cleaner and his duties stipulated his tasks.  So the IPR is his, and as such, the company has to agree a settlement to use the IPR.


There is a lot more to this, legal understanding of employment,  your duties etc.  But what the law does protect is the individuals rights, which cannot be override by catch all employment contract phrases such as "or what ever work or role we deem fit at the time".

Now move this to a seemingly less clear area.  You are employed to carry out data entry into a spreadsheet.   Your employment contract states your duties as compelling the data, maybe speaking to companies, sending forms etc.  However,  you have a keen interest in software development,  an in your own time you develope some code to make your task easier.  The company you work for, see this and passes it on to others in the company to use, in by doing so it save the company £100,000 per year.

The company has a software development team, a whole IT department etc. Who could have developed this.  They could have equally offered you employment within those departments seeing your potential.   However,  they choose to keep you on a low salaries data entry position. 

In this instance, you possess the IPR to the code, if you decided to take it to use in another job, it cannot be prevented.  However,  by allowing the company to use the code while you were employed there, it could be seen as your permission for them to continue to use it, unless you stipulate anywhere and at anytime, about any licencing restrictions.   These could.be free fair use while employed etc.

If you own the IPR, how much could you be paid for it? This is a fair question, and it's about worth.  How.much did it save the company, how much time did it take to develop and if you were asked by the company to make changes or update the code, in your own time.  You could quantify you time at a rate of £40 per hour, which would be an average.  If the company save £100,000 then anything from 1 to 5% would also seem fair.

To ensure when you write code and its not something you are employed to do, make your IPR case stronger by adding a license agreement. 



Friday, 7 August 2020

Deploying Angular .Net Core and Identity Server 4 onto iis

 

user is null when await this.userManager.signinCallback


Or at least that's where the problem started


To set the scene, I was using a vanilla .net core angular identity server 4 setup, to test what was happening.  So it's a good place to start to explain what was happening.

The Setup

I followed the step by step guide published here on the docs.microsoft.com site.  You would expect this to work.  To be fair, it does, in iis express or using the ng-serve command .

New Project

dotnet new angular -o pa2020 -au Individual

This gets us 90% of the way to a vanilla build.  However, to deploy onto a test server that has a certificate and running on port 443, we needed to add to the appSettings json file

"IdentityServer": { "Key": { "Type": "Store", "StoreName": "My", "StoreLocation": "CurrentUser", "Name": "CN=MyApplication" } }


Unbreakable - It Broke!

So simple, and you would expect it to work, and in iis express it does.  The error was

There was an error signing in: Error: (400)
at XMLHttpRequest.o.onload [as __zone_symbol__ON_PROPERTYload] (main-es2015.ae9ca0e58964647235f0.js:1)
at XMLHttpRequest.w (polyfills-es2015.5b10b8fd823b6392f1fd.js:1)
at a.invokeTask (polyfills-es2015.5b10b8fd823b6392f1fd.js:1)
at Object.onInvokeTask (main-es2015.ae9ca0e58964647235f0.js:1)
at a.invokeTask (polyfills-es2015.5b10b8fd823b6392f1fd.js:1)
at s.runTask (polyfills-es2015.5b10b8fd823b6392f1fd.js:1)
at c.invokeTask [as invoke] (polyfills-es2015.5b10b8fd823b6392f1fd.js:1)
at u (polyfills-es2015.5b10b8fd823b6392f1fd.js:1)
at XMLHttpRequest.p (polyfills-es2015.5b10b8fd823b6392f1fd.js:1)

But something strange, and it didn't look good.  The single page angular part was saying NOT LOGGED IN.  but click register, and the user is definitely authenticated, with access to the profile.

Debugging the code where this breaks lead me down several rabbit holes, one of which was the oidc-client setup.
Hidden way down in the depths of the authorize.service.ts line 113, the 
this.userManager.signinCallback(url); was throwing this error.  The usermanager was Observable which didn't help, neither was using fiddler to monitor the network.

The url and tokens were all as expected, even the routes were all good.  This is when I started to suspect the certificate - not sure what lead me to that, except somewhere in the back of my mind, years ago reading that IIS can sometimes decide refuse a call based on the certificate not being valid.

Certificates a plenty

I had a standard localhost certificate installed on my local box for iis testing, but as I also installed the wildcard certificate for pa2020 and set the hosts file to report to my local box, it mean I was ready to go.

I had published the to a local folder, again default settings, yet was getting the problem.  I decided to make the following changes.  However, only the combination of changes solved the isses.

1) consume the certificate at app startup
2) install the certificate outside of the iis system
3) Change App Pool identity, this bit was the missing glue;

Solution

This required changes to the code and to the IIS server

The certificate turned out to be partially the issue, so in the startup I added the following at the top of ConfigureServices
var cert = new X509Certificate2("my_private_key.pfx", Configuration["Authentication:Certificate:Pwd"]);

on the IIS Server I used certlm.msc to install the certificate

on the IIS Application Pool I changed the application pool identity from "ApplicationPool" to "NetworkService"

Now working as expected

Saturday, 30 April 2016

Flexible ADO.Net

Class Diagram




 using System.Collections.Generic;  
 using System.Data;  
 namespace POC.Common.DAL  
 {  
   public interface IDbManager  
   {  
     DataProvider ProviderType { get; set; }  
     string ConnectionString { get; set; }  
     IDbConnection Connection { get; }  
     IDbTransaction Transaction { get; }  
     IDataReader DataReader { get; }  
     IDbCommand Command { get; }  
     List<IDbDataParameter> ParameterList { get; }  
     void Open();  
     void BeginTransaction();  
     void CommitTransaction();  
     void AddParameters(IDbDataParameter param);  
     IDataReader ExecuteReader(CommandType commandType, string commandText);  
     DataSet ExecuteDataSet(CommandType commandType, string commandText);  
     object ExecuteScalar(CommandType commandType, string commandText);  
     int ExecuteNonQuery(CommandType commandType, string commandText);  
     void CloseReader();  
     void Close();  
     void Dispose();  
   }  
 }  
 using System;  
 using System.Data;  
 using System.Data.Odbc;  
 using System.Data.OleDb;  
 using System.Data.SqlClient;  
 namespace POC.Common.DAL  
 {  
   public static class DbManagerFactory  
   {  
     public static IDbConnection GetConnection(DataProvider providerType)  
     {  
       IDbConnection iDbConnection;  
       switch (providerType)  
       {  
         case DataProvider.SqlServer:  
           iDbConnection = new SqlConnection();  
           break;  
         case DataProvider.OleDb:  
           iDbConnection = new OleDbConnection();  
           break;  
         case DataProvider.Odbc:  
           iDbConnection = new OdbcConnection();  
           break;  
         case DataProvider.Oracle:  
           throw new NotImplementedException();  
         default:  
           return null;  
       }  
       return iDbConnection;  
     }  
     public static IDbCommand GetCommand(DataProvider providerType)  
     {  
       switch (providerType)  
       {  
         case DataProvider.SqlServer:  
           return new SqlCommand();  
         case DataProvider.OleDb:  
           return new OleDbCommand();  
         case DataProvider.Odbc:  
           return new OdbcCommand();  
         case DataProvider.Oracle:  
           throw new NotImplementedException();  
         default:  
           return null;  
       }  
     }  
     public static IDbDataAdapter GetDataAdapter(DataProvider providerType)  
     {  
       switch (providerType)  
       {  
         case DataProvider.SqlServer:  
           return new SqlDataAdapter();  
         case DataProvider.OleDb:  
           return new OleDbDataAdapter();  
         case DataProvider.Odbc:  
           return new OdbcDataAdapter();  
         case DataProvider.Oracle:  
           throw new NotImplementedException();  
         default:  
           return null;  
       }  
     }  
     public static IDbTransaction GetTransaction(DataProvider providerType)  
     {  
       IDbConnection iDbConnection = GetConnection(providerType);  
       IDbTransaction iDbTransaction = iDbConnection.BeginTransaction();  
       return iDbTransaction;  
     }  
     public static IDataParameter GetParameter(DataProvider providerType)  
     {  
       IDataParameter iDataParameter = null;  
       switch (providerType)  
       {  
         case DataProvider.SqlServer:  
           iDataParameter = new SqlParameter();  
           break;  
         case DataProvider.OleDb:  
           iDataParameter = new OleDbParameter();  
           break;  
         case DataProvider.Odbc:  
           iDataParameter = new OdbcParameter();  
           break;  
         case DataProvider.Oracle:  
           throw new NotImplementedException();  
       }  
       return iDataParameter;  
     }  
   }  
 }  
 using System;  
 using System.Collections.Generic;  
 using System.Data;  
 namespace POC.Common.DAL  
 {  
   public sealed class DbManager : IDbManager, IDisposable  
   {  
     private IDbCommand idbCommand;  
     private DataProvider providerType;  
     private IDbTransaction idbTransaction;  
     public DbManager(DataProvider providerType)  
     {  
       this.providerType = providerType;  
     }  
     public DbManager(DataProvider providerType, string connectionString)  
     {  
       this.providerType = providerType;  
       ConnectionString = connectionString;  
     }  
     public IDbConnection Connection { get; private set; }  
     public IDataReader DataReader { get; set; }  
     public DataProvider ProviderType  
     {  
       get { return providerType; }  
       set { providerType = value; }  
     }  
     public string ConnectionString { get; set; }  
     public IDbCommand Command  
     {  
       get { return idbCommand; }  
     }  
     public IDbTransaction Transaction  
     {  
       get { return idbTransaction; }  
     }  
     public void Open()  
     {  
       Connection =  
         DbManagerFactory.GetConnection(providerType);  
       Connection.ConnectionString = ConnectionString;  
       if (Connection.State != ConnectionState.Open)  
         Connection.Open();  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
     }  
     public void Close()  
     {  
       if (Connection.State != ConnectionState.Closed)  
         Connection.Close();  
     }  
     public void Dispose()  
     {  
       GC.SuppressFinalize(this);  
       Close();  
       idbCommand = null;  
       idbTransaction = null;  
       Connection = null;  
     }  
     public void AddParameters(IDbDataParameter param)  
     {  
       ParameterList.Add(param);  
     }  
     public void BeginTransaction()  
     {  
       if (idbTransaction == null)  
         idbTransaction =  
           DbManagerFactory.GetTransaction(ProviderType);  
       idbCommand.Transaction = idbTransaction;  
     }  
     public void CommitTransaction()  
     {  
       if (idbTransaction != null)  
         idbTransaction.Commit();  
       idbTransaction = null;  
     }  
     public IDataReader ExecuteReader(CommandType commandType, string commandText)  
     {  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
       idbCommand.Connection = Connection;  
       PrepareCommand(idbCommand, Connection, Transaction,  
               commandType,  
               commandText, ParameterList);  
       DataReader = idbCommand.ExecuteReader();  
       idbCommand.Parameters.Clear();  
       return DataReader;  
     }  
     public void CloseReader()  
     {  
       if (DataReader != null)  
         DataReader.Close();  
     }  
     private static void AttachParameters(IDbCommand command, IEnumerable<IDbDataParameter> commandParameters)  
     {  
       foreach (var idbParameter in commandParameters)  
       {  
         if ((idbParameter.Direction == ParameterDirection.InputOutput)  
           &&  
           (idbParameter.Value == null))  
         {  
           idbParameter.Value = DBNull.Value;  
         }  
         command.Parameters.Add(idbParameter);  
       }  
     }  
     private static void PrepareCommand(IDbCommand command, IDbConnection        connection, IDbTransaction transaction, CommandType commandType, string commandText,  
  IEnumerable<IDbDataParameter> commandParameters)  
     {  
       command.Connection = connection;  
       command.CommandText = commandText;  
       command.CommandType = commandType;  
       if (transaction != null)  
       {  
         command.Transaction = transaction;  
       }  
       if (commandParameters != null)  
       {  
         AttachParameters(command, commandParameters);  
       }  
     }  
     public int ExecuteNonQuery(CommandType commandType, string commandText)  
     {  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
       PrepareCommand(idbCommand, Connection, Transaction,  
               commandType, commandText, ParameterList);  
       var returnValue = idbCommand.ExecuteNonQuery();  
       idbCommand.Parameters.Clear();  
       return returnValue;  
     }  
     public object ExecuteScalar(CommandType commandType, string commandText)  
     {  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
       PrepareCommand(idbCommand, Connection, Transaction,  
               commandType,  
               commandText,  ParameterList);  
       var returnValue = idbCommand.ExecuteScalar();  
       idbCommand.Parameters.Clear();  
       return returnValue;  
     }  
     public DataSet ExecuteDataSet(CommandType commandType, string commandText)  
     {  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
       PrepareCommand(idbCommand, Connection, Transaction,  
               commandType,  
               commandText,  ParameterList);  
       var dataAdapter = DbManagerFactory.GetDataAdapter(ProviderType);  
       dataAdapter.SelectCommand = idbCommand;  
       var dataSet = new DataSet();  
       dataAdapter.Fill(dataSet);  
       idbCommand.Parameters.Clear();  
       return dataSet;  
     }  
     public List<IDbDataParameter> ParameterList  
     {  
       get { return parameterList ??   
 (parameterList = new List<IDbDataParameter>()); }  
     }  
     private List<IDbDataParameter> parameterList;  
   }  
 }  
 namespace POC.Common.DAL  
 {  
   public enum DataProvider  
   {  
     Oracle,  
     SqlServer,  
     OleDb,  
     Odbc  
   }  
 }  

Thursday, 24 April 2014

Running Flash swf in Windows Application Form - Disable Right Click

I recently ran into a problem that I resolved several years ago.  How to run a Flash swf movie in a windows application and disable the right mouse click menu.

There are many reasons for doing this.  At the time I was writing a game which used the right mouse click with either a forward or backward motion would zoom in or out.

Anyway, that's jumping forward a little too far.

I'm working on another game at the moment, uckers,so I have a beta swf to test with.

Loading the flash movie isn't complex you just need to load the COM Component for Shockwave Flash into the .net windows form project.




  1. Start a new Windows Form Project
  2. Add Shockwave Flash to Toolbox
    1. Right mouse click and select choose items
    2. Select Shockwave Flash and Select add
  3. Place new Component from toolbox to form 
  4. Change Form Settings
    remove the maximise and minimise functions and the fix the window size
  5. Go to code view
  6. Designer Code View
And thats it, right click disabled

Monday, 7 October 2013

Job Interviews - The Essay Test?

C# Coding tests.

Over the past couple of years testing prior to interview for roles has become more prevalent.  This has resulted in some interesting anomalies, most notably of how much of the question is open to interpretation.  Simple multiple choice test only test the knowledge that you have at your fingertips, and never the breadth and depth of understanding of that knowledge. Similarly, essay type scenario tests asking you to build a system based on some given facts, always miss vital parts or are open to interpretation. 

This is about the essay type question, in a normal requirements gathering phase of a project any anomalies, missing parts or clarifications can be ironed out at the start.  If an Agile process is being used then questions and clarifications can happen at any time.

Let’s examine a typical essay type scenario;
An object is moving across a 10 x 10 grid and you need to work out its final location.  Using a web service you will be provided with the movements of the object, Forward, Left (90 degrees) or Right(90 degrees). Each step is a single move.  After the first move the object is in position 1,0.  Once you have the location and final destination send this via web service.

If we examine this a bit closer, in other words the requirements gathering, and see if we have all the pieces to create a system.

An object is moving across a 10 x 10 grid.  How is this marked, 0 to 9 across the x and y axis, -4 to +5, mixture of both and do we need to care?  If we are given a location and movement then we need to know the reference points.  We can assume, as it is fairly common, that it would be 0 to 9.  Then we have the to decide where 0,0 is.  If we are told we can turn left or right and we start with 0,0 at the bottom left this would be completely different to stating at top left or bottom right.  Now the assumptions become a little more difficult.  Mathematically, you could assume the 0,0 would be bottom left as in most graphs.  However, if you are from a HTML5 canvas background where would you say 0,0 would be.  What about windows forms or apple ios, android Windows 8 mobile?

Movements of the object, Forward, Left (90 degrees) or Right(90 degrees). Each step is a single move. Not too difficult at first glance, but does this mean the object should just turn 90 and not move or turn and move?  Anyone ever played asteroids on the old Atari, I was in the navy in the eighties and this caused me to miss a lot of dates!  If we look at doing a Forward Left Right, does this mean that we have only moved one grid or three.  After years of asteroids I would assume one grid move many might assume three.

After the first move the object is in position 1,0.  There are two problems which we need to overcome with this statement.  Firstly, which grid did if move from?  It would be easy to assume 0, 0, but what if it was 2,0 or 1,1.  We know it only moves one grid per step, and we have assumed that a left or right is a turn not a move.  If we have made other assumptions, starting at bottom left of a 0-9 grid with x on the vertical axis and y on the horizontal axis.  Then moving from 0,0 to 1,0 turn left then forward would now mean our object would be in 1,-1 and as there is no -1 on the grid do we just assume that we stay at 0?

Let’s move onto the coding style.  

One thing I try and teach junior developers is that there is more than one way to write and piece of code, however, consistency is the key.  Not just consistency in how we individually code but in the way we code as a team.  I’ve had enough experience to know that in every project something will go wrong!  If it is all done the same way then at least the fix should be easier.  There are some principals which are always good to follow, and I will cover this in a few moments, but this is entirely down to the company and the team.  Each company, especially if using a process, should be following a set of guidelines.  Now just the ones similar to Microsoft’s best practices or SOLID principals but ones that have been adapted to suit the requirements of the business.

When an essay test is provided it rarely comes with the companies coding principals, leaving it to the whim of the marker to decide if his principals are better than yours so all you can do is follow your instinct, training and skill – follow both the Microsoft best practice and SOLID principals, throw in a bit of defensive programming and hope the person on the other end is looking for breadth and skill of an developer rather than someone who ticks boxes.  This is always going to be the difficult bit as the feedback from the company will never provide the solution they were looking for as a comparison tool.

Let me ask a few questions;

1)      Would you make a Console application, web application, widows application, class library or mix?
2)      What assumptions would you make?
3)      What would your design look like, not the code, just the design?


Saturday, 7 September 2013

Running IIS Express Remotely

IIS express usually runs under local host. To allow this to be seen by external computers you need to add binding information to the applicationhost.config file in
C:\Program Files (x86)\IIS Express\config

 
               
                   
               

               
                   
               

           


Important parts of this are the application pool, the name and the ID.  The application pool has to be the same for all the sites running in IIS8 express.

The name has to be unique and the ID has to be incremented.

Allow incoming connections.

Open command prompt and add rule

> netsh http add urlacl url=http://192.168.1.27:90/ user=everyone

In command prompt add a firewall rule

netsh advfirewall firewall add rule name="IISExpressWeb" dir=in protocol=tcp localport=90 profile=private remoteip=localsubnet action=allow

If running windows authentication alter the to deny anonymous authentication and allow Windows.

Running multiple sites.
Start iisexpress from the command prompt


"C:\Program Files (x86)\IIS Express\iisexpress.exe" /apppool:Clr4IntegratedAppPool 


 
 
 

Monday, 8 July 2013

Random Thoughts

When you working i'ts not always possible to just stop what your doing and blog and Idea or a train of thought.  This post is random  in it's creation with snippits of code, no explanations and no real flow.  However, this is where the useful bits start off - so if it's in here, at some point in the future it will become a blog.



Data Access Layer

A way of creating a common DAL for use in many project where ADO crud operations are used instead of Entity framework or NHibernate.


 using System.Collections.Generic;  
 using System.Data;  
 namespace Jannersoft.Common.DAL  
 {  
   public interface IDbManager  
   {  
     DataProvider ProviderType { get; set; }  
     string ConnectionString { get; set; }  
     IDbConnection Connection { get; }  
     IDbTransaction Transaction { get; }  
     IDataReader DataReader { get; }  
     IDbCommand Command { get; }  
     List<IDbDataParameter> ParameterList { get; }  
     void Open();  
     void BeginTransaction();  
     void CommitTransaction();  
     void AddParameters(IDbDataParameter param);  
     IDataReader ExecuteReader(CommandType commandType, string commandText);  
     DataSet ExecuteDataSet(CommandType commandType, string commandText);  
     object ExecuteScalar(CommandType commandType, string commandText);  
     int ExecuteNonQuery(CommandType commandType, string commandText);  
     void CloseReader();  
     void Close();  
     void Dispose();  
   }  
 }  
 using System;  
 using System.Data;  
 using System.Data.Odbc;  
 using System.Data.OleDb;  
 using System.Data.SqlClient;  
 namespace Jannersoft.Common.DAL  
 {  
   public static class DbManagerFactory  
   {  
     public static IDbConnection GetConnection(DataProvider providerType)  
     {  
       IDbConnection iDbConnection;  
       switch (providerType)  
       {  
         case DataProvider.SqlServer:  
           iDbConnection = new SqlConnection();  
           break;  
         case DataProvider.OleDb:  
           iDbConnection = new OleDbConnection();  
           break;  
         case DataProvider.Odbc:  
           iDbConnection = new OdbcConnection();  
           break;  
         case DataProvider.Oracle:  
           throw new NotImplementedException();  
         default:  
           return null;  
       }  
       return iDbConnection;  
     }  
     public static IDbCommand GetCommand(DataProvider providerType)  
     {  
       switch (providerType)  
       {  
         case DataProvider.SqlServer:  
           return new SqlCommand();  
         case DataProvider.OleDb:  
           return new OleDbCommand();  
         case DataProvider.Odbc:  
           return new OdbcCommand();  
         case DataProvider.Oracle:  
           throw new NotImplementedException();  
         default:  
           return null;  
       }  
     }  
     public static IDbDataAdapter GetDataAdapter(DataProvider providerType)  
     {  
       switch (providerType)  
       {  
         case DataProvider.SqlServer:  
           return new SqlDataAdapter();  
         case DataProvider.OleDb:  
           return new OleDbDataAdapter();  
         case DataProvider.Odbc:  
           return new OdbcDataAdapter();  
         case DataProvider.Oracle:  
           throw new NotImplementedException();  
         default:  
           return null;  
       }  
     }  
     public static IDbTransaction GetTransaction(DataProvider providerType)  
     {  
       IDbConnection iDbConnection = GetConnection(providerType);  
       IDbTransaction iDbTransaction = iDbConnection.BeginTransaction();  
       return iDbTransaction;  
     }  
     public static IDataParameter GetParameter(DataProvider providerType)  
     {  
       IDataParameter iDataParameter = null;  
       switch (providerType)  
       {  
         case DataProvider.SqlServer:  
           iDataParameter = new SqlParameter();  
           break;  
         case DataProvider.OleDb:  
           iDataParameter = new OleDbParameter();  
           break;  
         case DataProvider.Odbc:  
           iDataParameter = new OdbcParameter();  
           break;  
         case DataProvider.Oracle:  
           throw new NotImplementedException();  
       }  
       return iDataParameter;  
     }  
   }  
 }  
 using System;  
 using System.Collections.Generic;  
 using System.Data;  
 namespace Jannersoft.Common.DAL  
 {  
   public sealed class DbManager : IDbManager, IDisposable  
   {  
     private IDbCommand idbCommand;  
     private DataProvider providerType;  
     private IDbTransaction idbTransaction;  
     public DbManager(DataProvider providerType)  
     {  
       this.providerType = providerType;  
     }  
     public DbManager(DataProvider providerType, string connectionString)  
     {  
       this.providerType = providerType;  
       ConnectionString = connectionString;  
     }  
     public IDbConnection Connection { get; private set; }  
     public IDataReader DataReader { get; set; }  
     public DataProvider ProviderType  
     {  
       get { return providerType; }  
       set { providerType = value; }  
     }  
     public string ConnectionString { get; set; }  
     public IDbCommand Command  
     {  
       get { return idbCommand; }  
     }  
     public IDbTransaction Transaction  
     {  
       get { return idbTransaction; }  
     }  
     public void Open()  
     {  
       Connection =  
         DbManagerFactory.GetConnection(providerType);  
       Connection.ConnectionString = ConnectionString;  
       if (Connection.State != ConnectionState.Open)  
         Connection.Open();  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
     }  
     public void Close()  
     {  
       if (Connection.State != ConnectionState.Closed)  
         Connection.Close();  
     }  
     public void Dispose()  
     {  
       GC.SuppressFinalize(this);  
       Close();  
       idbCommand = null;  
       idbTransaction = null;  
       Connection = null;  
     }  
     public void AddParameters(IDbDataParameter param)  
     {  
       ParameterList.Add(param);  
     }  
     public void BeginTransaction()  
     {  
       if (idbTransaction == null)  
         idbTransaction =  
           DbManagerFactory.GetTransaction(ProviderType);  
       idbCommand.Transaction = idbTransaction;  
     }  
     public void CommitTransaction()  
     {  
       if (idbTransaction != null)  
         idbTransaction.Commit();  
       idbTransaction = null;  
     }  
     public IDataReader ExecuteReader(CommandType commandType, string commandText)  
     {  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
       idbCommand.Connection = Connection;  
       PrepareCommand(idbCommand, Connection, Transaction,  
               commandType,  
               commandText, ParameterList);  
       DataReader = idbCommand.ExecuteReader();  
       idbCommand.Parameters.Clear();  
       return DataReader;  
     }  
     public void CloseReader()  
     {  
       if (DataReader != null)  
         DataReader.Close();  
     }  
     private static void AttachParameters(IDbCommand command, IEnumerable<IDbDataParameter> commandParameters)  
     {  
       foreach (var idbParameter in commandParameters)  
       {  
         if ((idbParameter.Direction == ParameterDirection.InputOutput)  
           &&  
           (idbParameter.Value == null))  
         {  
           idbParameter.Value = DBNull.Value;  
         }  
         command.Parameters.Add(idbParameter);  
       }  
     }  
     private static void PrepareCommand(IDbCommand command, IDbConnection        connection, IDbTransaction transaction, CommandType commandType, string commandText,  
  IEnumerable<IDbDataParameter> commandParameters)  
     {  
       command.Connection = connection;  
       command.CommandText = commandText;  
       command.CommandType = commandType;  
       if (transaction != null)  
       {  
         command.Transaction = transaction;  
       }  
       if (commandParameters != null)  
       {  
         AttachParameters(command, commandParameters);  
       }  
     }  
     public int ExecuteNonQuery(CommandType commandType, string commandText)  
     {  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
       PrepareCommand(idbCommand, Connection, Transaction,  
               commandType, commandText, ParameterList);  
       var returnValue = idbCommand.ExecuteNonQuery();  
       idbCommand.Parameters.Clear();  
       return returnValue;  
     }  
     public object ExecuteScalar(CommandType commandType, string commandText)  
     {  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
       PrepareCommand(idbCommand, Connection, Transaction,  
               commandType,  
               commandText,  ParameterList);  
       var returnValue = idbCommand.ExecuteScalar();  
       idbCommand.Parameters.Clear();  
       return returnValue;  
     }  
     public DataSet ExecuteDataSet(CommandType commandType, string commandText)  
     {  
       idbCommand = DbManagerFactory.GetCommand(ProviderType);  
       PrepareCommand(idbCommand, Connection, Transaction,  
               commandType,  
               commandText,  ParameterList);  
       var dataAdapter = DbManagerFactory.GetDataAdapter(ProviderType);  
       dataAdapter.SelectCommand = idbCommand;  
       var dataSet = new DataSet();  
       dataAdapter.Fill(dataSet);  
       idbCommand.Parameters.Clear();  
       return dataSet;  
     }  
     public List<IDbDataParameter> ParameterList  
     {  
       get { return parameterList ??   
 (parameterList = new List<IDbDataParameter>()); }  
     }  
     private List<IDbDataParameter> parameterList;  
   }  
 }  
 namespace Jannersoft.Common.DAL  
 {  
   public enum DataProvider  
   {  
     Oracle,  
     SqlServer,  
     OleDb,  
     Odbc  
   }  
 }  


Implementation


   public class TestHarness  
   {  
     public IEnumerable<IPerson> GetAllPeople()  
     {  
       var dbManager = new DbManager(DataProvider.SqlServer);  
       dbManager.ConnectionString = Properties.Settings.Default.Connection;  
       try  
       {  
         dbManager.Open();  
         dbManager.ExecuteReader(CommandType.StoredProcedure, "sp_GetPersons");  
         while (dbManager.DataReader.Read())  
         {  
           Mapper.CreateMap<IDataReader, Person>();  
           var persons = Mapper.Map<IDataReader,IEnumerable<Person>>(dbManager.DataReader);  
           return persons;  
         }  
       }  
       finally  
       {  
         dbManager.Dispose();  
       }  
       return null;  
     }  
   }  

Testing


 [TestFixture]  
   public class TestHarnesTests  
   {  
     private Jannersoft.common.DALTestHarnes.TestHarness harness;  
     [SetUp]  
     public void SetUp()  
     {  
       harness = new TestHarness();  
     }  
     [TearDown]  
     public void TearDown()  
     {  
       harness = null;  
     }  
     [Test]  
     public void GetAllPeople_Return_ListOfPeople()  
     {  
       //Arrange  
       //Act  
       var output = harness.GetAllPeople();  
       //Assert  
       Assert.GreaterOrEqual(output.Count(), 0);  
     }  
   }  


Enum Extension


  public static class AttributesHelperExtensions  
   {  
     public static string GetStringValue<TEnum>(this TEnum value)  
     {  
       var type = value.GetType();  
       var fieldInfo = type.GetField(value.ToString());  
       var attribs = fieldInfo.GetCustomAttributes(  
         typeof(StringValueAttribute), false) as StringValueAttribute[];  
       return attribs.Length > 0 ? attribs[0].StringValue : null;  
     }  
   }