Method to execute when destroying class instance

Asked

Viewed 1,467 times

10

There is some way to execute a method automatically by destroying a class instance. 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 within 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();
     }
 }

See that I create the builder and call the method AbrirConexão.

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

  • I believe that Garbage Collector does this for you, by looking at this link http://msdn.microsoft.com/pt-br/library/66x5fx1b.aspx

  • @Meuchapeu, did not know this method "Destroyer". Knew the builder. But the destroyer did not. It was too much worth!

  • 1

    Because it is a connection, it is not legal for you to keep the connection open and only close when the Garbage Collector removes the object. It is more interesting you implement the Disposable Pattern. Take a look at the @bigown response!

  • I see here. I will use the same Disposable Pattern. Thanks @Renan.

2 answers

9


Disposable Pattern

Yes, there is, it’s called Disposable Pattern. It is not exactly in the destruction of the instance because in C# this destruction is not deterministic. That is, only when the Garbage Collector act is that the destruction really will happen, while this your connection will remain open and you will not know why it gives problems in other unrelated places.

In this pattern you create your class by implementing the interface IDisposable (creates the implementation of the Dispose()) doing what you want. With the implemented standard you can call the shutdown method when you want. Implementing it outright is not very simple even if it may seem. It is easy to make mistakes that will be difficult to resolve in the future.

But it’s not enough to create the class this way, you need to use the class the right way to ensure that the Dispose() be called even if an exception occurs. This is work for the using.

Using

This command was created precisely to manipulate the management of resources external to the application (any kind) terminating its use and existence when you want without taking risks. You can do the same thing manually. But you need to know what you’re doing, any slip-up and you’ll have not only a memory leak, but a resource leak, keeping something active that could no longer be in this state.

The using creates a block and the lifetime of the open resource in it will be just this block. As long as your code is running inside this block, the connection will be open, as soon as it leaves this block, no matter what the reason, the connection will be closed. It is worth noting that if you call any method inside the block, you will still be inside the block.

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

Of course it is possible to call the 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.

Destructor

There is still how to do the same through the method Finalize() or the destructor method ~NomeDaClasse() but in general it is a mistake to use them. There are a number of details that make them a correct option in very limited cases. If you don’t know 100% how to use them it’s because you don’t need them.

Standard . NET features already do it for you

In fact the connection you are opening already implements the IDisposable, so if you write the code the right way, it’s likely that this class SQL nor should exist. Take a look at other people’s code to see how they work with it.

You need to learn to use language patterns (using), otherwise it will keep reinventing the wheel and most likely it will come out square. Making the round wheel, at least in this case, is quite complicated, if you are not sure that you can, the wheel is better ready.

Documentation

I was looking for examples on the Microsoft website and I was open-mouthed because they posted some that induce bad practices. I know it’s just an example there and it wouldn’t have bad consequences, but for a layman, you read it and you think right is that way for everything.

I found examples of utility class for what you want. I don’t know if it serves exactly your purposes, but it’s the way.

Read more on documentation.

Anyway, the subject is complex, if you don’t devote enough on it, will cause chaos in its application.

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

Other resources:

  • Thanks @bigown.

  • @Thiagohenrique Solved your question you can accept one of the answers with the most correct. I think you’ve seen in [tour] how it is done. You can vote on all questions and answers from the site that have helped you in any way on any subject and think it would be useful also for other people.

5

To achieve your goal you will need to use using and the interface IDisposable in the following approach:

Inherit your class of IDisposable, that is to say: public class SQL : IDisposable so that you can implement the method public void Dispose() and within this method you will put the excerpt 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 need to use within the context of using so that at the end of all the method Dispose() be automatically called.

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.