I'm working on a plugin for QGis 3.x. The UI was created with Qt Designer and the plugin code boilerplate by Plugin builder.
I do have 3 main files in my project :
my_plugin.pywith the mainMyPluginclass andinitGui(),unload()andrun()methodsmy_plugin_dialog.pywith a simpleMyPluginDialogclass, that inherits fromQtWidgets.QDialogand theFORM_CLASSbased on my.uidesigner file. The class only contains__init__()method, itself callingself.setupUi()- an UI file created by Qt Designer 
my_plugin_dialog_base.ui 
I encounter some issues related to duplicate signals when starting/closing the plugin dialog. The most similar discussion on SO is the following : https://gis.stackexchange.com/questions/137160/qgis-plugin-triggers-function-twice
Yet, my problem is that my dialog object is created within the run() method (see below), so I can't access to my UI elements in the initGui() nor unload() methods.
So how can I disconnect signals, or define them so that closing the plugin also disconnects all my signals ?
Here is an excerpt of my_plugin.py content (created by Plugin Builder, except the last line related to connecting the signal and the slot) :
def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        icon_path = ':/plugins/my_plugin/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Start My Plugin'),
            callback=self.run,
            parent=self.iface.mainWindow())
        # will be set False in run()
        self.first_start = True
def run(self):
        """Run method that performs all the real work"""
        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            self.first_start = False
            self.dlg = MyPluginDialog()
        self.dlg.push_button_start.clicked.connect(self.on_pb_start) # connect signal to slot
And my_plugin_dialog.py:
FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'small_etl_dialog_base.ui'))
class MyPluginDialog(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(MyPluginDialog, self).__init__(parent)
        # Set up the user interface from Designer through FORM_CLASS.
        # After self.setupUi() you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
Maybe there is a proper way to access dialog objects inside the initGui() method ?