Method to execute when destroying instance of a class

8

Is there any way to automatically execute a method by destroying an instance of a class. I have a generic SQL class, where in the constructor I call a method that opens the connection. Only I want to close this connection automatically too, without having to create a method that closes the connection and call it inside several other methods of the class. See below:

public class SQL
{
      SQL(ObjConn obj)
      {
          AbrirConexao(obj);
      }

      public static void AbrirConexao(ObjConn objConn)
     {
         Conexao.ConnectionString = objConn.Acesso == "0" ? Utils.GetConnectionStringNerCard(objConn) : Utils.GetConnectionStringAutorizador(objConn);
         if (Conexao.State != ConnectionState.Open)
         Conexao.Open();
     }
 }

Notice that I create the constructor and call the AbrirConexão method.

Is there a native method that is automatically called by .NET when it destroys the instance of a class?

    
asked by anonymous 20.11.2014 / 13:30

2 answers

8

Disposable Pattern

Yes, it does exist, it's called Disposable Pattern.

  • It is not exactly in instance destruction because in C # this destruction is not deterministic. That is, only when the garbage collector act is that the destruction will actually happen, meanwhile your connection will remain open and you will not know because it gives problems in other unrelated places.

    In this pattern you create your class by implementing the IDisposable interface (it creates the Dispose() method implementation) doing what you want. With the default implemented you can call the shutdown method anytime you want. Implementing it straightaway is not very simple even though it may seem. It's easy to make mistakes that will be hard to solve in the future.

    But do not just create the class this way, you need to use the class the right way to ensure that Dispose() is called even if some exception occurs. This is work for using .

    Using

    This command was created precisely to handle the management of external resources to the application (any type) ending its use and existence when you wish without risk. You can do the same thing manually. But you need to know what you're doing, any slipping and you will have not only a memory leak, but a feature leak, keeping active something that could no longer be in this state.

    The using creates a block and the life time of the resource opened on it will be precisely this block. While your code is running inside this block, the connection is open, when you exit this block, no matter the reason, the connection will be closed. It is good to point out that if you call any method inside the block, you will still be inside the block.

    At first, before you know this feature well, it may seem more complicated, but keeping the opening and closing independently can cause nightmares in your application unless you have a domain that few experienced developers have.

    Of course you can call Dispose() manually. But in almost 100% of cases doing this is a mistake. And when it's right, it's almost always within the class itself.

    Destroyer

    You can also do the same with the Finalize() method or the destructor method ~NomeDaClasse() but in Overall it is a mistake to use them. There are a number of details that make them a correct choice in very limited cases. If you do not know 100% how to use them is because you do not need them.

    .NET standard features already do this for you

    Actually the connection you are opening already implements to IDisposable , then if you write the code the right way, it is likely that this SQL class should not even exist. Take a look at other people's code to see how they work with it.

    You need to learn to use language patterns (% with%), otherwise you will reinvent the wheel and most likely it will square out. Making the round wheel, at least in this case, is quite complicated, if you're not sure you can, the wheel is better.

    Documentation

    I was looking for examples on the Microsoft website and I just kept my mouth open because they posted some that would lead to bad practices. I know it's just an example there and it would not have bad consequences, but for those who are lay, read that and think that the correct way is for everything.

    I found utility class examples for what do you want. I do not know if it serves your purpose exactly, but it's the way.

    Read more in documentation .

    Anyway, the subject is complex, if you do not devote enough on it, it will cause chaos in your application.

    When you have a more ready code, put it in another question and ask peer review to see if you are on the right track.

    Other resources:

  • 20.11.2014 / 13:56
    3

    In order for your goal to be achieved you will need to use using and the IDisposable interface in the following approach:

    Inherit your class of IDisposable , that is: public class SQL : IDisposable so you can implement the public void Dispose() method and within that method you will put the snippet that needs to be run automatically.

    public void Dispose()
    {   
        if (Conexao.State == ConnectionState.Open)
            Conexao.Close();
    
        // outros códigos...
    }
    

    When you use the class SQL you will have to use it within the context of using so that at the end of everything the Dispose() method is called automatically.

    It would be something like:

    using(SQL s = new SQL(ObjConn objConn))
    {
        // faça o que tiver que fazer aqui
    }
    
    // após sair do contexto de 'using', o método Dispose será chamado automaticamente
    
        
    20.11.2014 / 14:27