Monday, April 21, 2008

Dependency Inversion Principle using Spring.Net

This post will continue from my previous post about how to implement the Dependency Inversion Principle. Below you will see an example that is in the same state as where my previous post ended, only I created a different context to make its usefulness more clear.

Interface: IDatabaseOperations
1
2
3
4
5
6
7
8
9
10
namespace SpringDIP
{
    public interface IDatabaseOperations
    {
        void Update(string[] parameters);
        void Delete(int id);

        string[] Select(int id);
    }
}
Class: MsSqlDatabaseProvider : IDatabaseOperations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace SpringDIP
{
    public class MsSqlDatabaseProvider : IDatabaseOperations
    {
        public void Update(string[] parameters)
        {
            // Do a Microsoft SQL Server 2008 specific update
        }
        public void Delete(int id)
        {
            // Do a Microsoft SQL Server 2008 specific delete
        }

        public string[] Select(int id)
        {
            // Do a Microsoft SQL Server 2008 specific select
            return (new string[] { "1", "Microsoft" });
        }
    }
}
Class: DatabaseProviderFactory
1
2
3
4
5
6
7
8
9
10
namespace SpringDIP
{
    public class DatabaseProviderFactory
    {
        public IDatabaseOperations GetDatabaseProvider()
        {
            return (new MsSqlDatabaseProvider());
        }
    }
}
So now what happens when we create another implementation of the IDatabaseOperations interface to interact with an Oracle database instead of the Microsoft SQL Server database. Well than we would have to change the references in the DatabaseProviderFactory and re-compile the classes that where changed / affected. And in that case you would maybe provide two different installers, one for Microsoft and one for Oracle, or maybe you would create a switch in a configuration file and use that value to make a choice between the two options. Anyway ugly is what comes to mind. Below is the solution when using Spring.Net:
Class: DatabaseProviderFactory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using Spring.Context;
using Spring.Context.Support;

namespace SpringDIP
{
    public class DatabaseProviderFactory
    {
        public IDatabaseOperations GetDatabaseProvider()
        {
            using (IApplicationContext ctx = ContextRegistry.GetContext())
            {
                return(ctx.GetObject("DatabaseProvider") as IDatabaseOperations);
            }
        }
    }
}
File: App.Config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<configuration>
  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
    </sectionGroup>
  </configSections>

  <spring>
    <context>
      <resource uri="config://spring/objects" />
    </context>
    <objects xmlns="http://www.springframework.net">
      <object name="DatabaseProvider" type="SpringDIP.MsSqlDatabaseProvider, SpringDIP" />
    </objects>
  </spring>
</configuration>
I only needed to change the DatabaseProviderFactory class and add some Spring.Net content in the App.Config file to have my application use the Spring.Net framework. In the DatabaseProviderFactory class I am refering to the Spring.Net configuration name DatabaseProvider and in this case Spring.Net will provide the MsSqlDatabaseProvider. In the future I will only need to provide the new DLL with for example the OracleDatabaseProvider and change the one line in the App.Config file, no need to re-compile.

I hope you found these examples helpful. Also take a look at the following links:

http://springframework.net/
http://www.developer.com/net/csharp/article.php/10918_3722931_1

No comments: