“My” namespace: Μας κακομαθαίνετε κύριε Roxe μου


Ένα νέο χαρακτηριστικό της Visual Basic 2005 είναι το “My” namespace. Το πρόβλημα που έρχεται να λύσει το συγκεκριμένο namespace είναι ότι το .ΝΕΤ Framework 2.0 με τις 4.500 νέες κλάσεις και τα 400.000 public members έχει γίνει αρκετά μεγάλο ώστε να φρενάρει την παραγωγικότητα όταν ψάχνουμε για το πώς μπορούμε να κάνουμε κάτι. Πλέον, αυτό που ξεχωρίζει τον παραγωγικό VB.NET developer από τον μη παραγωγικό δεν είναι η καλή γνώση της VB.NET αλλά η καλή γνώση του .NET Framework. Με ποια κλάση γράφουμε στο log, με ποια κλάση διαβάζουμε τα credentials του χρήστη, με ποια κλάση ελέγχουμε αν είναι πατημένο το caps lock. Ε, πλέον ένα μεγάλο τμήμα του .NET Framework έχει περάσει κάτω από το “My” namespace. Ωστόσο, όπως θα δούμε παρακάτω, δεν πρόκειται απλά για shortcuts που δείχνουν σε άλλα namespaces. Πρόκειται και για ρουτίνες που μας γλυτώνουν από το να γράφουμε τον ίδιο και τον ίδιο επαναλαμβανόμενο κώδικα.

Το My namespace αποτελείται από μια σειρά objects τα οποία είναι:

My.Application, βασίζεται στο παλιό Application class, αναπαριστά την εφαρμογή που τρέχει μας και μας παρέχει σχετικές πληροφορίες και functionality

My.Computer, που αναπαριστά τον υπολογιστή που τρέχει η εφαρμογή μας και μας παρέχει σχετικές πληροφορίες και functionality

My.Forms, μέσω του οποίου έχουμε πρόσβαση στις φόρμες από τις οποίες αποτελείται η εφαρμογή μας

My.Log, για να έχουμε πρόσβαση στο application log

My.Request, που μας δίνει το τρέχον web request

My.Resources, για πρόσβαση στα resources της εφαρμογής

My.Response, που μας δίνει το τρέχον web response

My.Settings, που μας επιτρέπει να χειριζόμαστε τα configuration settings της εφαρμογής

My.User, που μας δίνει πρόσβαση στον authenticated user που τρέχει την εφαρμογή

My.WebServices, που μας δίνει πρόσβαση στα web services που έχουμε κάνει reference στην εφαρμογή.

Θα δούμε μερικά παραδείγματα από τα παραπάνω τα οποία μπορούν να λειτουργήσουν ως ένα καλό σημείο εκκίνησης για να εξερευνήσετε αυτό το namespace. Μόνο που χρειάζεται λίγη προσοχή γιατί κάποια από αυτά τα objects μπορείτε να τα χρησιμοποιήσετε με τον ανάλογο τύπο εφαρμογής (WinForm, Console, WebApp)

My.Application

Στο My.Application έχουμε πρόσβαση σε πληροφορίες και υπηρεσίες σχετικές με την εφαρμογή που τρέχει. Για παράδειγμα, με το My.Application.CommandLineArgs μπορούμε να διαβάσουμε τις παραμέτρους με τις οποίες έχει ξεκινήσει η εφαρμογή και να πράξουμε τα δέοντα. Με το My.Application.Info μπορούμε να διαβάσουμε την version, το copyright, την περιγραφή, κλπ. Με το My.Application.OpenForms έχουμε ένα collection από τις ανοιχτές φόρμες της εφαρμογής.Ιδιαίτερο ενδιαφέρον έχει το object My.Application.Log. Πλέον το να γράψει κανείς στο application log είναι υπόθεση μιας γραμμής:

My.Application.Log.WriteEntry(“Some message here”)

ή

Catch ex As Exception
    My.Application.Log.WriteException(ex, _
    TraceEventType.Error, _
    "Exception with argument " & someArg )
End Try

Άλλη μια χρήση του My.Application object είναι ότι παρέχει μια σειρά από events με τα οποία μπορούμε να πιάσουμε διάφορα states της εφαρμογής, όπως γίνεται στις web εφαρμογές. Για παράδειγμα, μπορούμε να πιάσουμε την στιγμή που ξεκινάει η εφαρμογή (My.Application.Startup) ή αν πρόκειται για single-instance (έχουμε κάνει check το ανάλογο checkbox στις ρυθμίσεις) το My.Application.StartupNextInstance. Αυτά τα events δεν θα τα βρείτε έτοιμα στον designer όπως τα υπόλοιπα. Θα πρέπει να εισάγετε εσείς τον κώδικα απευθείας. Για παράδειγμα:

Private Sub MyApplication_StartupNextInstance(ByVal sender As Object, _
ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs) _
Handles Me.StartupNextInstance
…
…

Τέλος, μπορούμε να κάνουμε override κάποια methods της Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase που αποτελεί base class της My.Application, όπως το OnStartup, OnShutdown, OnRun, OnCreateSplashScreen και το σημαντικό OnUnhandledException.

My.Computer

Με το My.Computer μπορούμε να έχουμε πρόσβαση σε πληροφορίες και υπηρεσίες του host PC που τρέχει την εφαρμογή.Για παράδειγμα, μέσα στο My.Computer υπάρχει το My.Computer.FileSystem με το οποίο έχουμε ένα απλοποιημένο API για πρόσβαση στο FileSystem. Υπάρχει πλήθος από methods για να διαβάζουμε και να γράφουμε σε text και binary αρχεία (ακόμα και σε delimited) καθώς και να κάνουμε τυπικά file και folder operations. Ένα χαρακτηριστικό παράδειγμα είναι το εξής:

Dim contents As String = My.Computer.FileSystem.ReadAllText(filename)

Διαβάζουμε όλα τα περιεχόμενα ενός text file με μία γραμμή κώδικα!

Άλλο ένα σπουδαίο object είναι το My.Computer.Ports που μας δίνει πρόσβαση στα serial ports και μας γλυτώνει από αρκετό κώδικα. Στο παρελθόν, θα έπρεπε να καταφύγουμε σε Win32 API calls, ενώ τώρα:

Using

 com1 As IO.Ports.SerialPort = My.Computer.Ports.OpenSerialPort("COM1")
    com1.WriteLine(data)
End Using

Με τα My.Computer.Keyboard και My.Computer.Mouse μπορούμε να χειριστούμε εύκολα τις ανάλογες συσκευές ενώ με το My.Computer.Clipboard μπορούμε να χειριστούμε το …clipboard. Επίσης, με το My.Computer.Audio μπορούμε να παίξουμε ήχους. Όλα τα προηγούμενα είναι κώδικας της μιας γραμμής!

Τέλος, με το My.Computer.Network μπορούμε να κάνουμε upload και download αρχεία καθώς επίσης και να δούμε αν υπάρχει διαθέσιμο δίκτυο.

My.User

Πιστεύω οι περισσότεροι από μας έχουμε γράψει μια αντίστοιχη κλάση προκειμένου να χειριζόμαστε με ευκολία το security context του χρήστη της εφαρμογής. Το User object έχει μεθόδους όπως My.User.IsInRole και properties όπως My.User.CurrentPrincipal και My.User.IsAuthenticated. Έτσι, είναι εύκολο να γράψουμε κώδικα του τύπου:

If Not My.User.IsInRole("BUILDIN\Administrators") Then
    MsgBox("Sorry, you can't format the HD")
End If

Επίσης είναι σημαντικό ότι με το My.User.CurrentPrincipal μπορούμε όχι μόνο να διαβάσουμε αλλά και να ορίσουμε τον χρήστη που τρέχει την εφαρμογή.

My.Settings, My.Resources

Στη νέα VB.NET έχουμε τη δυνατότητα να αυτοματοποιήσουμε το persistence των ρυθμίσεων της εφαρμογής ανά χρήστη (πχ χρώματα, θέσεις παραθύρων, κλπ) ή συνολικά για την εφαρμογή (πχ working directory), εκεί που στο παρελθόν έπρεπε να γράψουμε αρκετό κώδικα για serialization/deserialization από custom κλάσεις. Πλέον αυτό γίνεται από το IDE και μέσα από το παράθυρο My Project. Αντίστοιχα λοιπόν, μέσα από το My.Settings μπορούμε να δουλέψουμε με αυτά τα settings. To ωραίο της υπόθεσης είναι ότι το My.Settings προσφέρει ένα strongly type τρόπο για να κάνουμε access τις ρυθμίσεις. Έτσι μπορούμε να πούμε:

Μy.Settings.ForeColor = Color.Azure

όπου το ForeColor το έχουμε δηλώσει στο My Project settings ως System.Drawing.Color. Φυσικά, έχουμε μεθόδους μέσω των οποίων μπορούμε να αποθηκεύσουμε, να φορτώσουμε και να κάνουμε initialize συνολικά τα settings.

Κάτι ανάλογο γίνεται με τα resources. Με το My.Resources μπορούμε να διαβάσουμε κάποιο resource που έχουμε ορίσει μέσα από το My Project. Για παράδειγμα:

Me.Icon = My.Resources.Icon1

My.WebServices

Με το My.WebServices μπορούμε να καλέσουμε web services χωρίς να χρειάζεται να δημιουργήσουμε instance. Έτσι, αντί να πούμε:

Dim converter As New webservicex.CurrencyConvertor
Dim euro As Double = dollarAmount * converter.ConversionRate(webservicex.Currency.USD,                                                              webservicex.Currency.EUR)

λέμε:

Dim euro As Double = dollarAmount *     My.WebServices.CurrencyConvertor.ConversionRate(webservicex.Currency.USD, webservicex.Currency.EUR)

Σημείωση: Το web service αυτό μπορείτε να το βρείτε εδώ http://www.webservicex.net/WS/WSDetails.aspx?CATID=2&WSID=10

My.Forms

Το My.Forms δίνει ένα default instance για κάθε μία φόρμα της εφαρμογής. Θυμίζει (και μάλλον γι αυτόν το λόγο φτιάχτηκε) τον τρόπο λειτουργίας της VB 6, ως προς το instantiation. Κατά τη γνώμη μου, πέρα από την ευκολία, είναι ένα βήμα πίσω. Το θέμα είναι να μπορέσουν οι developers της VB6 που δεν έχουν καλό ΟΟ background να αντιληφθούν τον νέο τρόπο που πρέπει να δουλεύουν. Πρέπει να μάθουν ότι η φόρμα είναι κλάση και πρέπει να έχω ένα instance με το οποίο θα δουλέψω. Δεν πρέπει να υπάρχουν μαγικά objects από το πουθενά. Είναι καλύτερη η βουτιά στα βαθιά μιας και αυτό είναι από τα πρώτα πράγματα που συναντά ένας VB6 developer. Αν αρχίσουμε να έχουμε τέτοιου είδους workarounds, κάποια στιγμή θα καταλήξουμε να έχουμε ADO.NET wrapper που να κάνει simulate το ADO.

Συμπεράσματα

Έχω αντικρουόμενες απόψεις για το My namespace. Από τη μία επιτυγχάνει το στόχο του, να αυξήσει την παραγωγικότητα του προγραμματιστή και είναι ευπρόσδεκτο, αν και ενδέχεται αρκετός κώδικας να υπάρχει ήδη σε βιβλιοθήκες που έχουμε αναπτύξει στο Framework 1.x.Από την άλλη μεριά όμως λειτουργεί αντίθετα ως προς μία βασική αρχή του .ΝΕΤ, ότι δεν παίζει ρόλο με τι γλώσσα γράφεις, σημασία έχει το Framework. Δεν μπορώ να καταλάβω γιατί αποφασίστηκε να παρέχεται μόνο μέσα από το Microsoft.VisualBasic.DLL και να μην υπάρχει διαθέσιμο για όλες τις γλώσσες, αφού έχουν ήδη παρουσιαστεί αρκετά άρθρα για το πώς μπορεί κανείς να το χρησιμοποιήσει μέσα από τη C# (αν και η ύπαρξη του My.Forms είναι αρκετή για να το αποδοκιμάσουν μετά βδελυγμίας οι C# developers). Πιστεύω ότι απομακρύνει αντί να συγκλίνει τις δύο γλώσσες και ιδιαίτερα όσοι δουλεύουν σε VB.NET και C# θα πρέπει να ξέρουν και το My και το μη-My τρόπο να κάνουν ό,τι κάνουν. Αυτό, μπορεί εκ πρώτης όψεως να μην φαίνεται ως μεγάλο πρόβλημα αλλά για αντιληφθείτε τι σημαίνει, δείτε πόσα πολλά posts εδώ στο DNZ, ενώ είναι για μία γλώσσα απαντώνται από developers άλλης γλώσσας, απλά και μόνο επειδή αφορούν το framework και όχι κάποιο feature της γλώσσας.

Advertisements


Σχολιάστε

Εισάγετε τα παρακάτω στοιχεία ή επιλέξτε ένα εικονίδιο για να συνδεθείτε:

Λογότυπο WordPress.com

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό WordPress.com. Αποσύνδεση / Αλλαγή )

Φωτογραφία Twitter

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Twitter. Αποσύνδεση / Αλλαγή )

Φωτογραφία Facebook

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Facebook. Αποσύνδεση / Αλλαγή )

Φωτογραφία Google+

Σχολιάζετε χρησιμοποιώντας τον λογαριασμό Google+. Αποσύνδεση / Αλλαγή )

Σύνδεση με %s