Replacing the following code with IoC (Castle Windsor)

If I had the code below, what are the best practice / design recommendations for replacing it with IoC (we want to use Castle Windsor). Since the using statement is responsible for creating the connection object, you cannot enter it directly into the constructor or method. Note. Using an SQL join as an apparently pure example, the main advantage here is mocking / unit testing.

public void CustomerRespository { .... public void Save(Customer customer) { using (var cn = new SqlConnection(connectionString)) { using (var cm = new SqlCommand(commandString, cn)) { .... cn.Open(); cm.ExecuteNonQuery(); } } } } 

I believe that there would be at least a few options, but since we are just starting out with IoC, I'm not sure that they will not cause us problems later and / or fly in front of IoC concepts. My approved approach will over-modify the approach as follows: can anyone highlight potential problems with it?

 public interface IDatabase { IDbConnection Connection(string connectionString); IDbCommand Command(string text, IDbConnection conn); } public class SqlDB : IDatabase { IDbConnection Connection(string connectionString) { return new SqlConnection(connectionString); } IDbCommand Command(string text, IDbConnection conn) { return new SqlCommand(text, conn); } } public interface ICustomerRespository { void Save(Customer customer) } public class CustomerRespository : ICustomerRespository { public IDatabase DB{get; private set;} public CustomerRespository( IDatabase db) { DB = db; } .... public void Save(Customer customer) { using (var cn = DB.Connection(connectionString)) { using (var cm = DB.Command(commandString, cn)) { .... cn.Open(); cm.ExecuteNonQuery(); } } } } 
+4
source share
2 answers

I used IoC, but not Castle, although they are all alike, so here is my catch on this.

I think you are on the right track, although I could use a separate factory to connect and command, or actually leave the connection open and the command running in another class, so the repository should not know this detail. Just have an IDatabase in the constructor of your class so that it is entered (or use a property if you use property-based injection). Replace SqlConnection and SqlCommand in your code with IDbConnection and IDbCommand.

UPDATE

They inherit / implement IDisposable, so you can use the using statement. Sorry for my mistake.

+1
source

The general approach seems fine to me, although I would not try to scoff at the IDbConnection and IDbCommand , as this can be complicated and, more importantly, it won’t tell you if the code works as intended.

This will allow you to change the database you are using, so you can use something like Sqlite for unit testing, and then test the code in your production database during integration testing.

You can also move the connection string to the IDatabase abstraction, which will simplify the clients.

+1
source

All Articles