Sunday, November 18, 2012

Could not load type - The Structuremap Error

Recently I got an structuremap error when I launch my application. The error message as follows
Error Message: Exception has been thrown by the target of an invocation. - 0%System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> 
System.TypeLoadException: Could not load type 'MetricsEngine.ApplicationServices.Metrics.IMetricService' from assembly 'MetricsEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

at WebApplication6.Bootstrapper.Registries.ClinicalIntegrationRegistry.<.ctor>b__0(IAssemblyScanner scanner)
at StructureMap.Configuration.DSL.Registry.Scan(Action`1 action) in c:\BuildAgent\work\767273992e840853\src\StructureMap\Configuration\DSL\Registry.cs:line 250
at WebApplication6.Bootstrapper.Registries.ClinicalIntegrationRegistry..ctor() in E:\Src\SolutionFolder\WebApplication6.Bootstrapper\Registries\MetricsRegistry.cs:line 33
--- End of inner exception stack trace ---
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at StructureMap.Graph.PluginGraph.ImportRegistry(Type type) in c:\BuildAgent\work\767273992e840853\src\StructureMap\Graph\PluginGraph.cs:line 232
at System.Collections.Generic.List`1.ForEach(Action`1 action)
at StructureMap.Configuration.DSL.Registry.ConfigurePluginGraph(PluginGraph graph) in c:\BuildAgent\work\767273992e840853\src\StructureMap\Configuration\DSL\Registry.cs:line 397
at StructureMap.Graph.AssemblyScanner.ScanForAll(PluginGraph pluginGraph) in c:\BuildAgent\work\767273992e840853\src\StructureMap\Graph\AssemblyScanner.cs:line 249
at StructureMap.Graph.PluginGraph.Seal() in c:\BuildAgent\work\767273992e840853\src\StructureMap\Graph\PluginGraph.cs:line 121
at StructureMap.PluginGraphBuilder.Build() in c:\BuildAgent\work\767273992e840853\src\StructureMap\PluginGraphBuilder.cs:line 72
at StructureMap.ObjectFactory.Initialize(Action`1 action) in c:\BuildAgent\work\767273992e840853\src\StructureMap\ObjectFactory.cs:line 65
at WebApplication6.Bootstrapper.Bootstrapper.RegisterContainer() in E:\Src\SolutionFolder\WebApplication6.Bootstrapper\Bootstrapper.cs:line 27
at WebApplication6.Bootstrapper.Bootstrapper.Bootstrap() in E:\Src\SolutionFolder\WebApplication6.Bootstrapper\Bootstrapper.cs:line 20

Reason:

My project looks very similar to the following picture.
In the above picture, I am referencing two different dlls from two different sources with the same name "MetricsEngine.dll". Now during the bootstrap the structuremap supposed to load it's referenced assembly(0.0.4696.21382) which is from vendor1, but it loads the assembly (1.0.0.0) from vendor2 which is referenced by WebApplication6.EngineServices. Though both the assemblies had different public key token and different version, it always loads the one from vendor2. The reason is structuremap uses reflection to load the assemblies dynamically at runtime; it scans though current project's referenced assemblies and it's references and so forth. In that way assembly MetricsEngine.dll from vendor1 and vendor2 are considered by the structuremap, now it picks the latest version, in our case it picks 1.0.0.0. It doesn't care about assembly's identity (public key token).

Temporary Solution:

I tried, But I couldn't figure out the right solution. For time being after downloading the assembly I renamed the assembly manually and referencing it in my project. I uninstalled that package from NuGet. That is, I am not using NuGet for one of the referencing assembly. Once I figure out the solution I will update this post.

Tuesday, November 13, 2012

The Moore's law and the Core's question

Preface:

This article describes, what can be the next generation computer? Processor making companies like Intel keep reducing the chip size or they increase the efficiency in the same chip size in their every next release. The hardware improvement for every two years is an inevitable requirement. The software operating data size increases day by day, the gaming softwares require very good hardware acceleration. Now the chip companies couldn't reduce the chip size as they could before; they are shipping more than one processor in one suite; they call them as dual core, quad core and so on.

Moore’s Law:

The number of transistors on integrated circuits doubles approximately every two years. Wiki Link. Many have predicted that Moore's Law will soon reach its end.

The semiconductor is the problem:

There is a limit for reducing the size, since we know the processors are made up of silicon and germanium type semiconductors. They are solid, after certain level we can’t reduce their size. What could be the solution for next generation?

Solution:

As of now, there are two ways.
  1. The quantum chips.
  2. The bio chips.
The Bio chips can be made up of either DNA or RNA.

Quantum computer chips:

Rather than encoding ones and zeroes into high and low voltages that switch transistors on and off, the idea is to use the electron's spin. The Princeton and the Wisconsin university are the pioneers of this research. The electron spin has two directions; clockwise and anticlockwise. Scientists are making use of this spin and generating binary digits.

Earlier Version of the Theory:

The earlier version of this theory when I studied in 2004 uses a pair of electrons. In quantum mechanics two entangled particles cannot be viewed individually, even after they leave the interaction zone, where they became entangled. They act as a single quantum object. For example, there are two electrons e1 and e2. They can be used to express 4 different binary numbers.

Example:

To express decimal 14 in quantum computers we need two pair of electrons.That is from the above pictures,

Anticlockwise e1 + Anticlockwise e2 + Anticlockwise e3 + clockwise e4 = 14
Where as in conventional computer we need 4 transistors. That is,

Transistor t1 high voltage + t2 high voltage + t3 high voltage + t4 low voltage = 1110 = (decimal 14)

Transistors are not comparable with electrons in terms of speed and the space requirement.

The Modern Version:

The modern theory deals with electron’s superposition; hence by using single electron we can express 4 different binary numbers as follows.

Example:

In the modern version only two electrons are required to express decimal 14. From the above pictures,
Superposition state anticlockwise e1 + Superposition state clockwise e2 = 14

The conventional computer expresses in the unit of bit, in quantum computer it is qbit (quantum bit). In this case it requires 2 qbits.

Advantages of quantum computers:

  1. Size problem will go away, since electrons are super tiny. Also weightless.
  2. The speed, the current conventional PC’s are about 1-5 GHz speed, quantum computer’s speed will be at about 1-5 THz.
  3. It can be highly parallel computer, because of the electron’s superposition. Understanding electron’s superposition requires some effort, I am not covering here. For now, consider it is an electron's transitioning state

Challenges:

Computer’s speed cannot be improved only by improving processor. Other peripherals’ speed is also important. Scientists are working on them as well. Some researchers suggesting LASER for bus interface.

The DNA computers:

The idea is to use high and low concentrations of these molecules to propagate signals instead of high and low voltages that switch transistors on and off. It is medically proven that DNA can store biological information. Scientists are trying, if DNAs’ can be a better storage for computers? Can they be used for calculations?

The DNA (Deoxyribonucleic acid) contains nucleobases. The primary nucleobases are A, T, C and G. Adenine, thymine, cytosine and guanine are the expansion for them respectively. The DNA is a pair of strands. The strand is made up of strings A with T and C with G. Here is the basic concept for DNA computing.

In a conventional computer, in a bit you can store either 1 or 0. But in a DNA computer you can represent a bit by using these four variables. That is, it can be.

Example:

The same example to represent decimal 14 for DNA computers will be much more clear,
TAGC + TACG => 1110 => 14

Benefits of DNA computers

  1. One Kg of DNA can store the data from all the electronic computers ever built.
  2. DNA computer of half inch will be more powerful than supercomputers.
  3. In one cubic centimeter we can fit 10 trillion DNA molecules. With this size, a computer would be able to hold 10 TB of data, and perform 10 trillion calculations at a time.
  4. By adding more DNA, more calculations could be performed. Scalability! Also they can be highly parallel.
  5. DNA’s extracted from cellular organisms, there will always be a supply of DNA. So these computers will be cheap.

The RNA computers:

The RNA (ribonucleic acid) molecules are very similar to DNA molecules; the only difference is; RNA uses U (uracil) instead of T (thymine). Hence A, G, C and U are called RNA-bases. Everything above mentioned for DNA computers is also applicable for RNA computers.

What can cause an asp.net web service error?

Preface:

Last month I faced a problem in our production server that all the newly hosted websites threw javascript error. When I debugged further with firebug, I noticed that the web service calls were failing.

Reason:

Our website requires ABCpdf 8.1 but our server had version 7.0, that caused the error. Because in the latest release we upgraded ABCpdf to 8.1 in our development environment, but in the production environment.

Technical Details:

The error message was '/Site_URL/SampleWebService.asmx' has not been pre-compiled, and cannot be requested. I couldn't figure out the problem with the help of eventlog or application log. Google search also didn't help me. Finally I figured out that, the problem can occur when CLR tries to load any earlier revison of dll file, but the application was compiled with the latest version of dll. In this case the CLR failed to load ABCpdf 7.0.

Saturday, September 8, 2012

Structuremap scopes and life cycles with example

This article is a detailed version of Basic structuremap scopes. I am trying to keep this article to focus generic DI/IOC container and not just for structuremap. While using any DI/IOC container you must be careful on two things.

  1. Request context
  2. From which context you are requesting object from the structuremap. Basically there are two contexts in a web application you can make request from. The first one is HttpContext and the other is Thread (ThreadContext).

  3. Object's scope
  4. In general the scope defines lifetime of an object. To be accurately with reference to DI/IOC container it is not the lifetime, it is better to say the object's accessiblity. That is, the object created in one scope cannot be referred in another scope. Also the DI/IOC container itself will not dispose the object at the end of the scope. We should explicitly dispose them or GC may take care at later point. For further reading How to dispose objects created by structuremap.


Let's look at the structuremap life cycles. Download the project for this example. I am using windows authentication in this project. Give your machine credentials to login the application. This project UI will not display any result. I am using log4net for results. Results are stored at "_ApplicationLogs\general.txt".

In this example I am using 'RuntimeHelpers.GetHashCode' to get the object hash code for each object. Since we write results in log file for objects comparison, the object hash code for each object helps us to make sure whether they are same object or different object.

  1. Example - transient objects - a.k.a. non-singleton
    • Registry class
    • In registry class, if you don't mention the life cycle, by default the structuremap creates transient object. That is, new object for each structuremap request.
      Code:
      public class ApplicationRegistry : Registry
      {
          public ApplicationRegistry()
          {
              Scan(scanner => 
              { 
                  For<IVehicle>().Use<Car>();                
              });            
          }
      }
      
    • Consumer code
    • In the following code, we are requesting structuremap two times. It returns different object each time. Have a look at the log result
      Code:
      public partial class  _Default : System.Web.UI.Page
      {
          ILog logger = log4net.LogManager.GetLogger("GeneralLog");
          protected void Page_Load(object sender, EventArgs e)
          {
              IVehicle Car = ObjectFactory.GetInstance<IVehicle>();
              logger.Info("First Car :" + Car.GetVehicleID() + " Login user:" + User.Identity.Name);
      
              Car = ObjectFactory.GetInstance<IVehicle>();
              logger.Info("Second Car :" + Car.GetVehicleID() + " Login user:" + User.Identity.Name);
          }
      }
      
    • Log result (log4net log result)
    • 09/08/2012 20:54:08.816 [12] INFO  GeneralLog 
      Message: First Car :3473973 Login user:My-PC\Pandian
      Exception: 
      
      09/08/2012 20:54:08.840 [12] INFO  GeneralLog 
      Message: Second Car :27605492 Login user:My-PC\Pandian
      Exception:
      

  2. Explicit call - transient objects - way 1
  3. The following approach works exactly similar way as explained in example-1.
    • Registry class
    • Code:
      For<IVehicle>().Transient().Use<Car>();
      

  4. Explicit call - transient objects - way 2
  5. This approach too works exactly similar way as explained in example-1 and example-2. The word “request” in the below code doesn't mean HttpRequest. The structuremap returns transient object for each request arrived at it.
    • Registry class
    • Code:
      For<IVehicle>().LifecycleIs(new UniquePerRequestLifecycle()).Use<Car>();
      

  6. Singleton objects
  7. Have a look at the following code and the log, it is very clear that the structuremap creates singleton object across requests. The object hash code 14145203 is same for all the four requests.
    • Registry class
    • Code:
      For<IVehicle>().Singleton().Use<Car>();
      
      For this example I logged in from two different browsers with two different credentials.
    • Log result (log4net log result)
    09/08/2012 22:15:52.277 [5] INFO  GeneralLog 
    Message: First Car :14145203 Login user:My-PC\Pandian
    Exception: 
    
    09/08/2012 22:15:52.313 [5] INFO  GeneralLog 
    Message: Second Car :14145203 Login user:My-PC\Pandian
    Exception: 
    
    09/08/2012 22:16:01.072 [5] INFO  GeneralLog 
    Message: First Car :14145203 Login user:My-PC\TestUser
    Exception: 
    
    09/08/2012 22:16:01.073 [5] INFO  GeneralLog 
    Message: Second Car :14145203 Login user:My-PC\TestUser
    Exception: 
    

  8. Explicit call - Singleton objects
  9. This method also creates singleton object across requests as explained in example 4. The only difference is that you can also pass constructor argument.
    Code:
    For<IVehicle>().Use(new Car());
    

  10. Tricky, it creates singleton object
  11. When we mention the instance in "Use" function it creates singleton object as I said in the 5th example. The "Trainsient()" request is ignored here.
    Code:
    For<IVehicle>().Transient().Use(new Car());
    

  12. Transient objects with constructor arguments.
  13. As opposed to example 5, the following statement in registry creates transient object and it lets you to pass constructor argument. Note, you should modify Car class to accept constructor argument.
    Code:
    For<IVehicle>().Use(context => new Car());
    

  14. Singleton per HttpRequest
  15. The following statement in registry class creates singleton object per request.I am logging in from two different machines. If you look at the log, you can see that it uses only one object per request.
    Code:
    For<IVehicle>().LifecycleIs(new HttpContextLifecycle()).Use<Car>();
    
    In the below log, the first two and the second two results are same. That means it creates new object for every request.
    09/08/2012 22:31:59.870 [19] INFO  GeneralLog 
    Message: First Car :19320046 Login user:My-PC\Pandian
    Exception: 
    
    09/08/2012 22:31:59.888 [19] INFO  GeneralLog 
    Message: Second Car :19320046 Login user:My-PC\Pandian
    Exception: 
    
    09/08/2012 22:32:07.944 [19] INFO  GeneralLog 
    Message: First Car :57289035 Login user:My-PC\TestUser
    Exception: 
    
    09/08/2012 22:32:07.945 [19] INFO  GeneralLog 
    Message: Second Car :57289035 Login user:My-PC\TestUser
    Exception: 
    

  16. Singleton per HttpSession
  17. Very similar to example 8, but it creates singleton object per session.
    Code:
    For<IVehicle>().LifecycleIs(new HttpSessionLifecycle()).Use<Car>();
    

  18. Thread context
  19. The following statement in registry class creates singleton object per thread.
    Code:
    For<IVehicle>().LifecycleIs(new ThreadLocalStorageLifecycle()).Use<Car>();
    
    I have changed a bit in the application's consumer code. There are three threads here. One parent thread and the other two threads are created by me. So there are three threads and three distinct objects.
    Code:
    public partial class  _Default : System.Web.UI.Page
    {
        ILog logger = log4net.LogManager.GetLogger("GeneralLog");
        //CLR runs this method as part of parent thread's execution
        protected void Page_Load(object sender, EventArgs e)
        {
            IVehicle Car = ObjectFactory.GetInstance<IVehicle>();
            logger.Info("First Car :" + Car.GetVehicleID() + "  Main Thread id: " + Thread.CurrentThread.ManagedThreadId);
    
            Car = ObjectFactory.GetInstance<IVehicle>();
            logger.Info("Second Car :" + Car.GetVehicleID() + "  Main Thread id: " + Thread.CurrentThread.ManagedThreadId);
      
            Thread thread1 = new Thread(new ThreadStart(ThreadFunction));
            thread1.Start();
    
            Thread thread2 = new Thread(new ThreadStart(ThreadFunction));
            thread2.Start(); 
        }
        private void ThreadFunction()
        {
            IVehicle Car = ObjectFactory.GetInstance<IVehicle>();
            logger.Info("First Car :" + Car.GetVehicleID() + " Thread id: " + Thread.CurrentThread.ManagedThreadId);
    
            Car = ObjectFactory.GetInstance<IVehicle>();
            logger.Info("Second Car :" + Car.GetVehicleID() + " Thread id: " + Thread.CurrentThread.ManagedThreadId);
        }
    }
    
    In the following log, there are three threads 6, 7 and 11. The three objects created for each thread. This is singleton per thread.
    09/08/2012 22:53:41.562 [6] INFO  GeneralLog 
    Message: First Car :14509978 Main Thread id: 6
    Exception: 
    
    09/08/2012 22:53:41.815 [6] INFO  GeneralLog 
    Message: Second Car :14509978 Main Thread id: 6
    Exception: 
    
    09/08/2012 22:53:41.998 [7] INFO  GeneralLog 
    Message: First Car :15366892 Thread id: 7
    Exception: 
    
    09/08/2012 22:53:41.999 [7] INFO  GeneralLog 
    Message: Second Car :15366892 Thread id: 7
    Exception: 
    
    09/08/2012 22:53:42.000 [11] INFO  GeneralLog 
    Message: First Car :7995840 Thread id: 11
    Exception: 
    
    09/08/2012 22:53:42.047 [11] INFO  GeneralLog 
    Message: Second Car :7995840 Thread id: 11
    Exception: 
    

  20. Hybrid context
  21. I have a special requirement for this example. Considering the above example-10, I need the first object (which is created in the parent thread) should be HttpContext scoped. The other two objects created inside the thread should be ThreadLocal scoped. In hybrid context the structuremap should automatically identify the request scope and it should return the object for the same scope. Generally HttpContext supersedes Thread context. This requirement can be solved as follows.
    Code:
    For<IVehicle>().HybridHttpOrThreadLocalScoped().Use<Car>();
    

    Also it is worth mentioning that, if you look at the HttpContext inside the main thread, it is available; it is not null. But it is not available for child threads; HttpContext is null.

    You can't find any difference in the log result, but the objects created for HttpContext are cached. Objects created for thread local scope are not cached.

Friday, August 24, 2012

Ways to prevent connection/resource leaks - Part 2

You may use these techniques to handle any expensive resource leaks, not just for connection leaks. In Part 1, I am explaining how to fix resource leaks in simpler ways. In this article I am explaining how to fix resource leaks with structuremap and how the structuremap object creation machnism works in multithreaded environment. Structuremap scopes explained here. Also I am explaining evils of singleton object in a multi-threaded environment.

  1. Fix for heterogeneous application - 1

  2. a. If your application is partially/not dependent on ORM.
    b. If your application uses DI/IOC tools like structure map.
    c. If your application is single threaded.

    Solution


    The fact is that singleton objects created by structuremap for HttpContext scope are cached. To create singleton object use the following line of code in your structuremap registry.
    Code:
    For<SqlConnection>().HttpContextScoped().Use(new SqlConnection());
    
    Since it is cached, you can easily dispose it in the global.asax file's Application_EndRequest event by calling the following method.
    Code:
    ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
    

  3. Fix for heterogeneous application - 2

  4. a. If your application is partially/not dependent on ORM.
    b. If your application uses DI/IOC tools like structure map.
    c. If your application is multi-threaded, but uses limited number of threads.

    Solution


    The following line in structuremap registry creates object for both thread scope and http context scope.
    Code:
    For<SqlConnection>().HybridHttpOrThreadLocalScoped().Use(new SqlConnection());
    

    It requires two operations. One is thread scope cleanup and the other is HttpContext scope cleanup.

    In structuremap, thread scoped singleton objects are not cached. The above line of code creates one singleton object for each thread. The thread scoped singleton objects must be disposed at your own cost. That means you must explicitly dispose at the end of every thread in your application. Such as

    Code:
    ObjectFactory.GetInstance<SqlConnection>().Dispose();
    

    Now, the HttpContext scoped objects can be disposed by calling the following method in Application_EndRequest event.

    Code:
    ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
    

  5. Fix for heterogeneous application - 3

  6. a. If your application is partially/not dependent on ORM.
    b. If your application uses DI/IOC tools like structure map.
    c. If you are restoring HttpContext.Current within the thread. That is, within a thread you cannot access HttpContext variables, it will be null. But in some cases you may need HttpContext data within a thread and you pass HttpContext.Current as parameter to the thread. This way you restore the HttpContext within a thread. Such as
    Code:
    //Thread method, this method will be executed in parallel by more than 1 threads. ThreadParameters is a class created by me.
    private void BindDataThread(ThreadParameters parameter)
    {
     //I need to access data from HttpContext, restoring it.
     HttpContext.Current = parameter.CurrentHttpContext;
     var connection = ObjectFactory.GetInstance<SqlConnection>();
    }
    

    If you use the above line, it will create a singleton object for HttpContextScope and the same object will be served for various threads from structuremap. Since SqlConnection object is not thread safe it will throw random errors. That means, all threads will be using the same SqlConnection object, one thread will be in retrieving data from the database and the other will be in opening the connection, the third one will be in closing the connection by using the same connection object.

    So what happens to the thread local scope? That I mentioned “HybridHttpOrThreadLocalScoped” in the structuremap registry to create object for thread local scope. Well, in structuremap the HttpContext scope takes precedence by checking HttpContext.Current != null. As soon as you assign "HttpContext.Current = parameter.HttpContext", it will only create object for HttpContext scope within a thread; but it supposed to create object for thread local scope!!

    So what can be the solution?

    Code:
    //For().HybridHttpOrThreadLocalScoped().Use(new SqlConnection());
    For<IVehicle>().LifecycleIs(new ThreadLocalStorageLifecycle()).Use<Car>();
    

    You may try by using the second option (the uncommented) instead of the first option (the commented) as I mentioned above.

    How it will work?

    This creates a singleton object for each thread. That is, the structuremap creates objects per thread basis, no matter for which context the object is requested.

    On the other hand, it can be overhead. Objects created in the page handlers/controllers are run by main thread. We have to dispose them too.

    We can use HttpModules or Application_EndRequest to dispose objects created in main thread.

    Otherwise, if we have an option in DI/IOC container to specify to take ThreadLocalScope lifecyle as precedence, it can be bit more easier.

    Note: If you are using nested DataReader this approach will not work. See the code below

    Code:
    
    int departmentCode;
    //The following statement opens an SqlConnection and going to be active throughout the scope of "using" statement.
    using (SqlDataReader departmentReader = GetDepartmentReader()) 
    {
     while (departmentReader.Read())
     {
      departmentCode = Convert.ToInt32(departmentReader.GetValue(0));
      //The following line will try to use an another reader in the same thread, Since we made the SqlConnection as singlton per thread, this code will again open the same connection and will throw error.
      using (SqlDataReader employeeReader = GetEmployeeReader(departmentCode))
      {
       ...
       ...
      }
     }
    }
    

    All this approaches may raise following questions in your mind.

  7. Why can't you use transient objects?
  8. Transient objects are not cached anywhere in structuremap, you can’t reference back and dispose them.

  9. Why can’t you use nested containers?
  10. For the situations that we discussed so far, I feel the nested containers are overhead. I can simply use “using” statement instead. Both provides the similar solution.


Back to Part-1

Monday, August 20, 2012

Ways to prevent connection/resource leaks - Part 1

You may use these techniques to handle any expensive resource leaks, not just for connection leaks. In Part 2, I am explaining how to fix resource leaks with structuremap. Also I am explaining evils of singleton object in a multi-threaded environment.

Preface:
This article describes ways to prevent connection leaks (i.e. SqlConnection leaks) when using DataReader.

In case of dataset you don’t have to open connection explicitly, to retreive data, the dataset automatically opens and closes the connection even if the connection's current state is closed. In most of the situation we tend to have our own application specific wrapper/API class for ADO.Net operations. Since dataset follows disconnected architecture, the connection can be easily closed in the wrapper/API class’s method itself. The problem lies in DataReader, here I am explaining two simple ways to prevent resource leaks for those situations

  1. Fix for classic application


  2. a. If your application is not using ORM like NHibernate.
    b. If your application is not using DI/IOC tool like StructureMap.

    Solution 1 - Traditional way


    Use “using” statement to dispose connection/DataReader objects.
    Code:
    
    protected void PrintData()
    { 
        string connString = "Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;";
        using (SqlConnection conn = new SqlConnection(connString))
        {
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = "SELECT ID, Name FROM Customers";
    
            conn.Open();
    
            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                while (dr.Read())
                Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
            }//DataReader will be disposed
        } //Connection object will be disposed
    }
    

    Note:
    Avoid try/catch/finally block to dispose your object, I feel “using” makes my code much cleaner. "using” also disposes the object in the case of exception.

    Solution 2 – Disposing at Application_EndRequest


    This solution will be optimal when
    a.If you are using a wrapper class to operate objects
    b.If your application is very old and missed to close the connection in many places. The refactor may take long time, here is the quick solution.
    Code:
    //Cache the connection object in the wrapper/API when they are getting created
    public void CacheConnectionObject(SqlConnection connection)
    { 
        if (HttpContext.Current != null)
        {
            lock (_ConnectionSyncLock_) //Ensuring thread safe
            {
                IList<SqlConnection> connectionList;
                if (HttpContext.Current.Items[StringConstantKeys.SqlConnections] == null)
                {
                    connectionList = new List<SqlConnection>();
                }
                else
                {
                    connectionList = (IList<SqlConnection>)HttpContext.Current.Items[StringConstantKeys.SqlConnections];
                }
    
                connectionList.Add(connection);
                HttpContext.Current.Items[StringConstantKeys.SqlConnections] = connectionList;
            }
        }
    }
    
    Code:
    //Call this method in the Application_EndRequest event
    public void CloseSqlConnectionObjects()
    {    
        lock (_ConnectionSyncLock_) //Ensuring thread safe
        {
            if (HttpContext.Current != null && HttpContext.Current.Items[StringConstantKeys.SqlConnections] != null)
            {
                foreach (SqlConnection connection in (IList<SqlConnection>)HttpContext.Current.Items[StringConstantKeys.SqlConnections])
                {
                    try
                    {
                        if (connection != null)
                        {
                            if (connection.State != ConnectionState.Closed)
                            {
                                connection.Close();
                                //connection.Dispose(); I am not disposing it, since connection pool may reuse the same connection object across the HttpContext.
                            }
                        }
                    }
                    catch//Intentionally suppressing the errors, because this method called at the end of the request.
                    { }
                }
            }
        }
    }
    

  3. Fix for the enterprise application
  4. If your application is fully dependent on ORM

    Solution


    You don’t have to dispose anything related to connection object. Generally the ORM softwares are well designed to handle connection leaks. In case of NHibernate, it operates database in the context of NHibernate Session. Once the operation is over, it disposes the NHibernate Session as well as the objects associated with it.


Next-Part-2