'_RestrictData' or '_RestrictContext' in addon 2.8
Use a dynamic enum or a string property.
When an addon is enabled, it is imported and the register method called. At this stage both the data and context are restricted. The window manager is one of the few objects outside the restriction.
See no reason to have the persistent handler, have taken it out. Using it as an items loader from context when the addon is registered is no good either.
Cleaned up some other stuff, to prevent warnings in the console, eg the panel class name in form UPPERCASE_PT_TitleCase.
Try and avoid import *.
Test script: Have made the enum property dynamic and populated it with the immediate children of the context scene.  For example sake have added a string property and used a prop search to give options from same.
Have shown and example of an operator enum menu in panel layout.
bl_info = {
    &quot;name&quot; : &quot;test&quot;,
    &quot;author&quot; : &quot;Diego Quevedo&quot;,
    &quot;description&quot; : &quot;&quot;,
    &quot;blender&quot; : (2, 80, 0),
    &quot;version&quot; : (0, 1, 0),
    &quot;location&quot; : &quot;&quot;,
    &quot;warning&quot; : &quot;&quot;,
    &quot;category&quot; : &quot;Generic&quot;
}



import bpy
from bpy.props import EnumProperty, StringProperty
from bpy.types import (
    AddonPreferences,
    Operator,
    Panel,
    PropertyGroup
)
    
    
class TEST_OT_Test(bpy.types.Operator):
    bl_idname = &quot;view3d.test&quot;
    bl_label = &quot;Test&quot;
    bl_category = &quot;Test&quot;
    bl_space_type = &quot;VIEW_3D&quot;
    bl_region_type = &quot;UI&quot;
    bl_options = {'REGISTER', 'UNDO'}
    
    def enum_items(self, context):
        scene = context.scene
        return [(c.name,) * 3 for c in scene.collection.children]
    
    coll_enum:  EnumProperty( 
        items=enum_items,     
        name=&quot;Collections&quot;
    )
    
    coll_name: StringProperty()

    def test(self, context, collection):        
        print(&quot;test&quot;, collection)
        
        
    @classmethod
    def poll(self, context):
       return context.scene.collection.children

    def invoke(self, context, event):
        return context.window_manager.invoke_props_dialog(self)

    def execute(self, context):
        self.test(context, self.coll_enum)
        return {'FINISHED'}
    
    def draw(self, context):
        layout = self.layout
        scene = context.scene

        col = layout.column()
        col.prop(self, &quot;coll_enum&quot;)
        col.prop_search(self, &quot;coll_name&quot;, scene.collection, &quot;children&quot;)

####################
class TEST_PT_Test(bpy.types.Panel):
    bl_idname = &quot;TEST_PT_Test&quot;
    bl_label = &quot;Test&quot;
    bl_category = &quot;Test&quot;
    bl_space_type = &quot;VIEW_3D&quot;
    bl_region_type = &quot;UI&quot;

    def draw(self, context):
        layout = self.layout

        col = layout.column()

        col.operator(&quot;view3d.test&quot;, text=&quot;test&quot;, icon = &quot;DOT&quot;)
        col.operator_menu_enum(&quot;view3d.test&quot;, &quot;coll_enum&quot;)


            
def register():    
    bpy.utils.register_class(TEST_OT_Test)
    bpy.utils.register_class(TEST_PT_Test)
  

def unregister():
    bpy.utils.unregister_class(TEST_OT_Test)
    bpy.utils.unregister_class(TEST_PT_Test)
  

if __name__ == &quot;__main__&quot;:
    register()

Edit:
For the case of adding a collection to a scene with no child collections can:
    def enum_items(self, context):
        scene = context.scene
        if not scene.collection.children:
            foo = bpy.data.collections.new(&quot;Foo&quot;)
            scene.collection.children.link(foo)
        return [(c.name,) * 3 for c in scene.collection.children]

which IMO works best in conjunction  with the operator menu enum layout.