<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.studentguru.gr/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="el"><title type="html">Delicate Sound of Development</title><subtitle type="html">Journal για creative &amp;amp; non-creative δραστηριότητες.
Development and more...:)</subtitle><id>http://www.studentguru.gr/blogs/grnemo/atom.aspx</id><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/default.aspx" /><link rel="self" type="application/atom+xml" href="http://www.studentguru.gr/blogs/grnemo/atom.aspx" /><generator uri="http://communityserver.org" version="3.1.20917.1142">Community Server</generator><updated>2009-03-14T21:20:00Z</updated><entry><title>[Μαθαίνοντας Design Patterns] Model – View – ViewModel</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2010/03/11/design-patterns-model-view-viewmodel.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2010/03/11/design-patterns-model-view-viewmodel.aspx</id><published>2010-03-11T00:30:22Z</published><updated>2010-03-11T00:30:22Z</updated><content type="html">&lt;p align="justify"&gt;Συνεχίζοντας τη σειρά με τα &lt;a href="http://www.studentguru.gr/blogs/grnemo/archive/tags/design+patterns/default.aspx" target="_blank"&gt;design patterns&lt;/a&gt;, σε αυτό το post γίνεται μία αναφορά στο MVVM, μέσα από μία αρκετά απλοϊκή προσέγγιση. Θα περιγραφεί το pattern, θα δωθούν μερικές base classes, ένα utility για το πώς γίνεται type-safely raise ένα event για ανανέωση UI, καθώς και ένα μικρό παράδειγμα, με Bing Maps σε μία Silverlight εφαρμογή.&lt;/p&gt;  &lt;h4&gt;Τί είναι το MVVM;&lt;/h4&gt;  &lt;p align="justify"&gt;Το Model – View – ViewModel είναι ένα πρότυπο σχεδίασης για το σχεδιασμό διεπαφών χρήστη, το οποίο έχει επηρροές τόσο από το Model View Presenter, όσο και από το Model View Controller. Είναι γνωστό&amp;#160; και ως &lt;a href="http://www.martinfowler.com/eaaDev/PresentationModel.html" target="_blank"&gt;Presentation Model&lt;/a&gt; (σχεδόν ίδιο)(PM στο εξής), όπως το έχει καταγράψει ο Martin Fowler. To Model – View – ViewModel (&lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx" target="_blank"&gt;MVVM&lt;/a&gt; στο εξής) είναι επίσης ένας καθιερωμένος τρόπος, για τη δημιουργία εφαρμογών που βασίζονται και σε XAML και επιλέχθηκε για την ευελιξία που παρέχει στον προγραμματιστή κατά την ανάπτυξη (decoupling View-Model). Το design pattern που περιγράφεται στη συνέχεια με τη βοήθεια του παραδείγματος σε silverlight, παρουσιάζεται έχοντας κατα νου το ισχυρό πλαίσιο databinding του silverlight (η αντιστοιχία στοιχείου οθόνης με κανονικό Property ενός object). &lt;/p&gt;  &lt;p align="justify"&gt;Ξεκινώντας την περιγραφή του MVVM, αναφέρουμε ότι παρέχει (όπως και το PM) ένα επίπεδο αφαίρεσης του View (της εικόνας δηλαδή που φαίνεται στον χρήστη / XAML) στο οποίο ορίζεται τόσο η κατάστασή του, όσο και η συμπεριφορά του. Έστω ότι έχουμε την οθόνη διαχείρισης καταστημάτων μίας εταιρίας πώλησης παπουτσιών. Υπάρχουν δύο εκδόσεις για την εν λόγω οθόνη, μία που παρουσιάζει όλα τα καταστήματα (datagrid με μία λίστα) και μία που ενεργοποιείται όταν αλλάζουμε ιδιότητες από κάποιο κατάστημα (αρκετά controls, όπως textboxes κτλ με τα οποία μπορούμε να καταχωρούμε πληροφορίες για ένα selected store από την προηγούμενη σελίδα). Οι δύο οθόνες λέγονται αντίστοιχα Master και Detail σελίδες. Έστω ότι έχουμε την Detail σελίδα να αναπτύξουμε. Στη συνέχεια περιγράφεται πώς το MVVM μπορεί να διαχωρίσει τις αρμοδιότητες, για διαφορετικές ενέργειες που λαμβάνουν χώρα πίσω από την οθόνη. &lt;/p&gt;  &lt;p align="justify"&gt;Τα τρία στοιχεία που περιγράφονται είναι τρία διαφορετικά αντικείμενα στη μνήμη και έχουν πεδία και μεθόδους. Έτσι λοιπόν έχουμε το &lt;strong&gt;View&lt;/strong&gt; (τονίζω πάλι ότι αναφερόμαστε σε XAML αρχείο) το οποίο περιέχει διάφορα controls με τα οποία μπορεί να αλληλεπιδράσει ο χρήστης. Κάθε control που περιέχεται, μπορεί να εμφανίσει πληροφορία είτε σε μορφή κειμένου είτε σε κάτι πιο πολυμεσικό. &lt;/p&gt;  &lt;p align="justify"&gt;Έστω ότι έχουμε ένα πεδίο κειμένου (textboxes) και έναν επιλογέα με μία μοναδική επιλογή κάθε φορά (combobox). Τα δύο αυτά controls, δένουν τις τιμές τους με ιδιότητες (properties) του &lt;strong&gt;ViewModel&lt;/strong&gt; μέσω μηχανισμού databinding. Προγραμματιστικά το databinding ανάμεσα στο View και στο ViewModel (που περιέχει όλη την πληροφορία που δείχνει/ανανεώνει/… το View) γίνεται πάρα πολύ εύκολα, μιας και θέτουμε το ViewModel αντικείμενο, ως το πλαίσιο δεδομένων (datacontext) του View (βλ. παράδειγμα). Αν κάποια τιμή, σε κάποιο property αλλάξει, τότε η ίδια ιδιότητα ενεργοποιεί ένα γεγονός (κάνει raise ένα event propertychanged) που υποδηλώνει ότι άλλαξε τιμή και έτσι ενημερώνει το View ότι άλλαξε η τιμή για το συγκριμένο user control (για παράδειγμα ένα textbox – πεδίο εισαγωγής κειμένου). Κάθε πληροφορία δηλαδή, που είναι databound με ένα control όταν αλλάξει, ενημερώνει το UI ότι άλλαξε και ότι θα πρέπει να ανανεωθεί. Για να μπορεί ένα αντικείμενο (το ViewModel στην περίπτωσή μας) να αλληλεπιδρά με αυτόν τον τρόπο θα πρέπει να υλοποιεί το INotifyPropertyChanged interface. Έτσι λοιπόν ανανεώνεται και η αντίστοιχη πληροφορία στον χρήστη. Σε αντίθετη περίπτωση, όταν ένας χρήστης πατήσει ένα κουμπί, μία εντολή (Commanding) θα εκτελεστεί στο ViewModel και θα πραγματοποιήσει όλες τις αλλαγές στα δεδομένα του μοντέλου (τα οποία περιέχονται στο ίδιο το αντικείμενο του ViewModel). &lt;/p&gt;  &lt;p align="justify"&gt;To &lt;strong&gt;Model&lt;/strong&gt; είναι το αντικείμενο το οποίο καλείται από το ViewModel για λειτουργίες πρόσβασης στα δεδομένα. Στην περίπτωσή μας έχουμε δομικές μονάδες που περιγράφουν το πεδίο της εφαρμογής (customers, orders, κτλ). Αξίζει να κρατήσουμε τρία πράγματα: &lt;a href="http://www.studentguru.gr/blogs/grnemo/image_1AC54FB6.png"&gt;&lt;img style="border-right-width:0px;margin:25px 40px 0px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" align="left" src="http://www.studentguru.gr/blogs/grnemo/image_thumb_625728DD.png" width="269" height="247" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;To View ΔΕΝ γνωρίζει το Model (γιατί δεν απαιτείται κάτι τέτοιο εννοιολογικά) &lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;To ViewModel ΔΕΝ γνωρίζει τίποτα για View (εξαρτάται, ίσως είναι θέμα προθέσεων του προγραμματιστή)&lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;To Model ΔΕΝ γνωρίζει τίποτα για View&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;p align="justify"&gt;Στις XAML εφαρμογές, το View είναι η οθόνη που σχεδιάζουμε στο Expression Blend (την εφαρμογή της Microsoft για σχεδιασμό σελίδων), το ViewModel αναπτύσσεται στο Visual Studio και το Model είναι στην ουσία οι κλάσεις που χρησιμοποιούμε για το πεδίο της εφαρμογής μας οι οποίες περιέχουν όλες τις ιδιότητες οι οποίες υπάρχουν στο αντικείμενο. Στις RIA εφαρμογές το κανονικό μοντέλο υπάρχει στον server και μία πιο μινιμαλιστική έκδοση στον client, για να μπορεί να διαχειρίζεται τα αντικείμενα. Για παράδειγμα στην σελίδα με την επεξεργασία ενός στιγμιότυπου της οντότητας Shoe (π.χ. για rowId = 5) το ViewModel έχει ως ένα από τα πεδία του, ένα αντικείμενο τύπου shoe, το οποίο δηλώνεται στο Model. To Model, έχει στον server την κανονική έκδοση της οντότητας Shoe, ορίζοντας πρόσθετες ιδιότητες αν είναι απαραίτητο (που δεν εμφανίζονται στον client). &lt;/p&gt;  &lt;p align="justify"&gt;Στις ακόλουθες ιεραρχίες μπορούμε να δούμε την κλάση ViewControl που είναι στην ουσία η οθόνη μας, που γνωρίζει το ViewModel και το έχει θέσει ως το Data Context της. Υπάρχει ένα κάπως well defined API μέσα από generic type constraints.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Base Classes&lt;/h4&gt;  &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;public class ViewControl : UserControl, IView   
{    
&amp;#160;&amp;#160;&amp;#160; private IViewModel viewModel;    
&amp;#160;&amp;#160;&amp;#160; public ViewControl()    
&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160; }    
&amp;#160;&amp;#160;&amp;#160; protected ViewControl(IViewModel viewModel) : this()    
&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SetViewModelInternal(viewModel);    
&amp;#160;&amp;#160;&amp;#160; }    
&amp;#160;&amp;#160;&amp;#160; public virtual TViewModel GetViewModel&amp;lt;TViewModel&amp;gt;()    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; where TViewModel : class, IViewModel    
&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return this.viewModel as TViewModel;    
&amp;#160;&amp;#160;&amp;#160; }    
&amp;#160;&amp;#160;&amp;#160; public virtual void SetViewModel(IViewModel model)    
&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.SetViewModelInternal(model);    
&amp;#160;&amp;#160;&amp;#160; }    
&amp;#160;&amp;#160;&amp;#160; private void SetViewModelInternal(IViewModel model)    
&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.viewModel = model;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; this.DataContext = model;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyChanged.Raise(() =&amp;gt; DataContext);    
&amp;#160;&amp;#160;&amp;#160; }    
&amp;#160;&amp;#160;&amp;#160; #region INotifyPropertyChanged Members    
&amp;#160;&amp;#160;&amp;#160; public event PropertyChangedEventHandler PropertyChanged;    
&amp;#160;&amp;#160;&amp;#160; #endregion    
}    
    
public interface IView : INotifyPropertyChanged    
{    
}    
    
    
public interface IView&amp;lt;TViewModel&amp;gt; : IView    
&amp;#160;&amp;#160;&amp;#160; where TViewModel : IViewModel    
{    
&amp;#160;&amp;#160;&amp;#160; TViewModel ViewModel { get; set; }    
}    
    
public interface IViewModel : INotifyPropertyChanged    
{   }   
    
public interface IViewModel&amp;lt;TView&amp;gt; : IViewModel    
&amp;#160;&amp;#160;&amp;#160; where TView : IView    
{    
&amp;#160;&amp;#160;&amp;#160; TView View { get; set; }     
}    
    
public abstract class ViewModel&amp;lt;TView&amp;gt;    
&amp;#160;&amp;#160;&amp;#160; where TView : IView    
{    
&amp;#160;&amp;#160;&amp;#160; public bool IsDesignTime    
&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return (Application.Current == null) || (Application.Current.GetType() == typeof(Application));    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    
&amp;#160;&amp;#160;&amp;#160; }    
&amp;#160;&amp;#160;&amp;#160; #region INotifyPropertyChanged Members    
&amp;#160;&amp;#160;&amp;#160; public event PropertyChangedEventHandler PropertyChanged;    
&amp;#160;&amp;#160;&amp;#160; #endregion    
}&lt;/textarea&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Έστω η περίπτωση που έχω controls που στέλνουν εντολές, buttons, κλπ κλπ. Θα πρέπει να υπάρχει μία δομή στο XAML, που θα δηλώνει το πια εντολή είναι αυτή που θα πρέπει να εκτελεστεί όταν πατηθεί το κουμπί. Στην περίπτωση του code behind μπορούμε να παίξουμε με handlers αλλά με MVVM μπορώ να έχω μία διαφορετική προσέγγιση. Γιατί να μη εκμεταλλευτώ το μοντέλο του MVVM και να “βρωμίσω” το code behind μου με κώδικα hard-wired με το View? Έτσι λοιπόν ένα σημείο κλειδί είναι να χρησιμοποιήσουμε Commands. Στο WPF υπάρχουν πραγματικά commands που σε συνδυασμό με τα routed events δημιουργούν την έννοια του routed command, αλλά δεν θα μιλήσουμε εδώ γι’ αυτό. Στο Silverlight (3) υπάρχει το ICommand interface το οποίο είναι στην ουσία το εξής, και θα αναλύσουμε σε κάποια άλλη συζήτηση για το commanding σε MVVM:&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;interface ICommand    
{     
&amp;#160;&amp;#160;&amp;#160; void Execute(object parameter);     
&amp;#160;&amp;#160;&amp;#160; bool CanExecute(object parameter);     
&amp;#160;&amp;#160;&amp;#160; event EventHandler CanExecuteChanged;     
}&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Bing Maps MVVM&lt;/h4&gt;  &lt;p&gt;Στο συγκεκριμένο παράδειγμα παραθέτω το ViewModel μίας οθόνης που έχει ένα Bing Maps control. Θέλω σε αυτόν το χάρτη, να παρουσιάσω καταστήματα που έχουν χωρική πληροφορία και θα εμφανιστούν στον χάρτη μας. Τι χρειάζομαι ως business πληροφορία; Ένα collection από καταστήματα (τύπου ObservableCollection που μπορεί να ενημερώνει όταν επιδέχεται αλλαγές) και ίσως ένα SelectedStore για να γνωρίζω πιο store έχει επιλεγχθεί (για απεικόνιση περισσότερων πληροφοριών).&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;public class StoreMapViewModel : ViewModel&amp;lt;IStoreMapView&amp;gt;, IStoreMapViewModel    
&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private BusinessLogicDomainContext domainContext = new BusinessLogicDomainContext();     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public StoreMapViewModel()     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Load();     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }   &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private ObservableCollection&amp;lt;Store&amp;gt; stores;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public ObservableCollection&amp;lt;Store&amp;gt; Stores     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return stores;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; stores = value;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyChanged.Raise(() =&amp;gt; Stores);     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private Store selectedStore;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public Store SelectedStore     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; selectedStore = value;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyChanged.Raise(() =&amp;gt; SelectedStore);     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return selectedStore;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }   &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }   
    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; private void Load()     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //Εδώ υπάρχει κώδικας για ανάκτηση όλων των stores. Χρησιμοποιήθηκε το WCF Ria Services κομμάτι του WCF    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; //το οποίο σχεδιάστηκε ειδικά για τις ανάγκες Line of Business silverlight applications    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; LoadOperation&amp;lt;Store&amp;gt; loadedStores = this.domainContext.Load(this.domainContext.GetStoresQuery());     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; loadedStores.Completed += (sender, e) =&amp;gt; { Stores = new ObservableCollection&amp;lt;Store&amp;gt;(domainContext.Stores); };     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    
    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;     
&amp;#160;&amp;#160; }&lt;/textarea&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Αναφορικά με το όμορφο API για το raising των property changed events, προκειμένου να γράφουμε κάτι του στυλ Raise(“PropertyName”), θεωρώ πιο όμορφo να χρησιμοποιήσω έναν type safe τρόπο με lambda που na παρέχει το property name, αντί να γράφω κάτι error prone όπως το όνομα του property με το χέρι. &lt;em&gt;&lt;font size="1"&gt;(Credits to original &lt;a href="http://blog.decarufel.net/2009/07/how-to-use-inotifypropertychanged-type_22.html" target="_blank"&gt;author&lt;/a&gt;)&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;public static void Raise(this PropertyChangedEventHandler handler, Expression&amp;lt;Func&amp;lt;object&amp;gt;&amp;gt; propertyExpression)   
if (handler != null)    
{    
&amp;#160;&amp;#160;&amp;#160; // Retreive lambda body    
&amp;#160;&amp;#160;&amp;#160; var body = propertyExpression.Body as MemberExpression;    
&amp;#160;&amp;#160;&amp;#160; if (body == null)    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new ArgumentException(&amp;quot;&amp;#39;propertyExpression&amp;#39; should be a member expression&amp;quot;);&amp;#160; 
&amp;#160;&amp;#160;&amp;#160; // Extract the right part (after &amp;quot;=&amp;gt;&amp;quot;)    
&amp;#160;&amp;#160;&amp;#160; var vmExpression = body.Expression as ConstantExpression;    
&amp;#160;&amp;#160;&amp;#160; if (vmExpression == null)    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new ArgumentException(&amp;quot;&amp;#39;propertyExpression&amp;#39; body should be a constant expression&amp;quot;);&amp;#160; 
&amp;#160;&amp;#160;&amp;#160; // Create a reference to the calling object to pass it as the sender    
&amp;#160;&amp;#160;&amp;#160; LambdaExpression vmlambda = System.Linq.Expressions.Expression.Lambda(vmExpression);    
&amp;#160;&amp;#160;&amp;#160; Delegate vmFunc = vmlambda.Compile();    
&amp;#160;&amp;#160;&amp;#160; object vm = vmFunc.DynamicInvoke();&amp;#160; 
&amp;#160;&amp;#160;&amp;#160; // Extract the name of the property to raise a change on    
&amp;#160;&amp;#160;&amp;#160; string propertyName = body.Member.Name;    
&amp;#160;&amp;#160;&amp;#160; var e = new PropertyChangedEventArgs(propertyName);    
&amp;#160;&amp;#160;&amp;#160; handler(vm, e);    
}&lt;/textarea&gt;&lt;/p&gt;  &lt;h4&gt;Bing Maps View&lt;/h4&gt;  &lt;p align="justify"&gt;To View μας που περιέχει το bing maps control, είναι ένα μάθημα για databinding με XAML, templating κτλ από μόνο του, αλλά ήθελα να το δείξω εδώ για πληρότητα. Παρατηρήστε πόσο εύκολα και κατανοητά δηλώνω το που αντλώ πληροφορία για τα pushpins (Stores collection) και πιό member διαλέγω για να ανακτήσω την πληροφορία (LocationInformation).&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;&amp;lt;controls:ViewControl    
&amp;#160;&amp;#160;&amp;#160; xmlns=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;    
&amp;#160;&amp;#160;&amp;#160; xmlns:x=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;    
&amp;#160;&amp;#160;&amp;#160; xmlns:d=&amp;quot;http://schemas.microsoft.com/expression/blend/2008&amp;quot;    
&amp;#160;&amp;#160;&amp;#160; xmlns:mc=&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;    
&amp;#160;&amp;#160;&amp;#160; xmlns:m=&amp;quot;clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl&amp;quot;    
&amp;#160;&amp;#160;&amp;#160; mc:Ignorable=&amp;quot;d&amp;quot;    
&amp;#160;&amp;#160;&amp;#160; xmlns:controls=&amp;quot;clr-namespace:Infrastructure.Controls;assembly=Infrastructure&amp;quot;    
&amp;#160;&amp;#160;&amp;#160; d:DesignWidth=&amp;quot;640&amp;quot; d:DesignHeight=&amp;quot;480&amp;quot;    
&amp;#160;&amp;#160;&amp;#160; x:Class=&amp;quot;Views.StoreMapView&amp;quot;&amp;gt;    
&amp;#160;&amp;#160;&amp;#160; &amp;lt;UserControl.Resources&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DataTemplate x:Key=&amp;quot;LogoTemplate&amp;quot;&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;m:Pushpin m:MapLayer.Position=&amp;quot;{Binding LocationInformation}&amp;quot; /&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/DataTemplate&amp;gt;    
&amp;#160;&amp;#160;&amp;#160; &amp;lt;/UserControl.Resources&amp;gt;    
&amp;#160;&amp;#160;&amp;#160; &amp;lt;Grid x:Name=&amp;quot;LayoutRoot&amp;quot;&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ScrollViewer x:Name=&amp;quot;PageScrollViewer&amp;quot; Style=&amp;quot;{StaticResource PageScrollViewerStyle}&amp;quot; Margin=&amp;quot;0,0,-38,0&amp;quot; &amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;StackPanel x:Name=&amp;quot;ContentStackPanel&amp;quot; Style=&amp;quot;{StaticResource ContentStackPanelStyle}&amp;quot;&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBlock x:Name=&amp;quot;HeaderText&amp;quot; Style=&amp;quot;{StaticResource HeaderTextStyle}&amp;quot;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Text=&amp;quot;{Binding Path=ApplicationStrings.StoreMapPageTitle, Source={StaticResource ResourceWrapper}}&amp;quot;/&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;StackPanel x:Name=&amp;quot;MapControl&amp;quot; Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;m:Map x:Name=&amp;quot;MyMap&amp;quot; CredentialsProvider=&amp;lt;!--Εδώ τοποθετούνται τα δικά μας credentials--&amp;gt; Width=&amp;quot;519&amp;quot; HorizontalAlignment=&amp;quot;Left&amp;quot;&amp;gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;m:MapItemsControl x:Name=&amp;quot;ListOfItems&amp;quot;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ItemTemplate=&amp;quot;{StaticResource LogoTemplate}&amp;quot;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ItemsSource=&amp;quot;{Binding Stores}&amp;quot;&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/m:MapItemsControl&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/m:Map&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ComboBox Height=&amp;quot;23&amp;quot; Name=&amp;quot;comboBox1&amp;quot; Width=&amp;quot;150&amp;quot; VerticalContentAlignment=&amp;quot;Top&amp;quot;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; VerticalAlignment=&amp;quot;Top&amp;quot; ItemsSource=&amp;quot;{Binding Stores}&amp;quot; DisplayMemberPath=&amp;quot;storeName&amp;quot;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; SelectionChanged=&amp;quot;comboBox1_SelectionChanged&amp;quot; /&amp;gt;    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/StackPanel&amp;gt;   &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/StackPanel&amp;gt;   
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/ScrollViewer&amp;gt;    
&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Grid&amp;gt;    
&amp;lt;/controls:ViewControl&amp;gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Ελπίζω να έδωσα αρκετό food for thought. Enjoy Silverlight &amp;amp; MVVM!!!&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=[Μαθαίνοντας Design Patterns] Model – View – ViewModel&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2010/03/11/design-patterns-model-view-viewmodel.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="[Μαθαίνοντας Design Patterns] Model – View – ViewModel";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2010/03/11/design-patterns-model-view-viewmodel.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=110999" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="design patterns" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/design+patterns/default.aspx" /><category term="bing maps" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/bing+maps/default.aspx" /><category term="silverlight" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/silverlight/default.aspx" /></entry><entry><title>Closures στη C#</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2010/03/09/closures-c.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2010/03/09/closures-c.aspx</id><published>2010-03-08T22:13:00Z</published><updated>2010-03-08T22:13:00Z</updated><content type="html">&lt;p align="justify"&gt;Τελικά τα closures είναι ένα απλό concept, που όταν το κατανοήσει κάποιος, το βλέπει τετριμμένο μετά. Αν μπορούσα να δανειστώ από κάπου, δυό λόγια για ορισμό, νομίζω η wikipedia το περιγράφει αρκετά καλά. Τα closures είναι μία ιδέα των γλωσσών προγραμματισμού, που επιτρέπει, σε συναρτήσεις που αντιμετωπίζονται ως first-class objects, τον συσχετισμό ελεύθερων μεταβλητών τους, με τον λεκτικό περιβάλλοντα χώρο της συνάρτησης. Στη συνέχεια θα ήθελα να διατυπώσω το εν λόγω concept όσο πιο σύντομα γίνεται, δανειζόμενος (μερικώς ή πλήρως) κώδικα από το βιβλίο C# in Depth του Jon Skeet και από το Reference της C#.&lt;/p&gt; &lt;h4&gt;First – class functions στην C#&lt;/h4&gt; &lt;p align="justify"&gt;First class functions είναι συναρτήσεις που έχουν όλες τις ιδιότητες των αντικειμένων, μπορούν να δημιουργηθούν δυναμικά, μπορούν να συμμετέχουν σε δομές δεδομένων, να ανατεθούν ως παράμετροι, καθώς και να επιστραφούν από κλήσεις άλλων συναρτήσεων. Στην οικογένεια των γλωσσών προγραμματισμού, η C# ανήκει σε εκείνες που υποστηρίζουν first class functions, μέσω του τύπου δεδομένων &lt;a href="http://msdn.microsoft.com/en-us/library/ms173171.aspx" target="_blank"&gt;Delegate&lt;/a&gt; και όλης της πραγματικότητας γύρω από αυτό (anonymous methods, lambdas, expression trees). Θυμίζω ότι σε γενικές γραμμές Delegate είναι ένας τύπος δεδομένων (reference type) όπου παρέχει έναν ασφαλή τρόπο για να ενθυλακώσουμε συναρτήσεις (είτε static είτε instance). Ένα Delegate μπορεί να αναφέρεται μόνο σε συναρτήσεις που είναι συμβατές με το signature που περιγράφει. &lt;/p&gt; &lt;p align="justify"&gt;Η έννοια των πραγματικών closures, ήρθε στην C# με την έκδοση 2.0, υπό τη μορφή των anonymous delegates (και κατεπέκταση στα lambdas), που σε γενικές γραμμές επιτρέπουν την προσπέλαση (read &amp;amp; write) μεταβλητών που δηλώνονται έξω από το scope αυτών. Χωρίς true closure support, είναι π.χ., η Java και ότι πιο κοντινό έχει σε αυτό το concept, είναι τα anonymous inners classes. Ένα simplistic closure support υπολογίζεται ότι θα υποστηριχθεί με την έλευση της νέας έκδοσης 7, το &lt;a href="http://www.infoq.com/news/2009/11/jdk7-simple-closures" target="_blank"&gt;Σεπτέμβρη 2010&lt;/a&gt;.&lt;/p&gt; &lt;h4&gt;Περιβάλλον ενός lambda&lt;/h4&gt; &lt;p align="justify"&gt;Στο παρακάτω μπλοκ κώδικα θα δούμε διαφορετικούς τύπους μεταβλητών, αναφορικά, με την θέση τους σε σχέση με το lambda.&lt;/p&gt; &lt;p align="justify"&gt;&lt;i&gt;Outer/free Variables&lt;/i&gt;: Οι μεταβλητές που βρίσκονται στο λεκτικό περιβάλλον του delegate (δηλαδή το scope τους περιλαμβάνει το delegate) θεωρούνται ώς πιθανές μεταβλητές που μπορούν να χρησιμοποιηθούν από αυτό. Ελεύθερες μεταβλητές λοιπόν για ένα lambda, είναι όσες δεν δηλώνονται μέσα στο scope του και όσες δεν δηλώνονται στις παραμέτρους τους (τότε θα λέγονταν bound variables). Μαθηματικώς, για παράδειγμα στον Fourier, για κάποιο χ τα a0, a1, a2, .., bn είναι ελεύθερες μεταβλητές (μπορούν να πάρουν τιμές από τον περιβάλλοντα χώρο) :&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/image_44170CF5.png"&gt;&lt;img src="http://www.studentguru.gr/blogs/grnemo/image_thumb_11B33976.png" style="border:0px none;display:inline;" title="image" alt="image" border="0" height="47" width="250" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p align="justify"&gt;Όταν ένα free variable δεσμευτεί στο περιβάλλον του lambda, λέγεται ότι είναι ένα από τα &lt;i&gt;Captured Variables, &lt;/i&gt;τα οποία είναι εξωτερικές μεταβλητές που χρησιμοποιούνται μέσα στο lambda. Ότι δεν είναι free variable, λέγεται bound variable, όπως για παράδειγμα η μεταβλητή &lt;i&gt;Anonymous Local &lt;/i&gt;που ανήκει στις μεταβλητές που δηλώνονται και χρησιμοποιούνται μέσα στο lambda.&lt;/p&gt; &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;int outerVariable = 5;
string capturedVariable = &amp;quot;captured&amp;quot;;
if (DateTime.Now.Hour==23)
{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp; int normalLocalVariable = DateTime.Now.Minute;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(normalLocalVariable);
} 
ThreadStart x = delegate() 
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string anonLocal=&amp;quot;local to anonymous method&amp;quot;;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(capturedVariable + anonLocal); 
&amp;nbsp;&amp;nbsp;&amp;nbsp; };
x(); &lt;/textarea&gt;&lt;/p&gt; &lt;p align="justify"&gt;Όταν μέσα σε ένα lambda γίνεται αναφορά σε μία εξωτερική μεταβλητή, λέμε ότι η μεταβλητή αυτή, έχει δεσμευτεί (captured) και η ίδια ζει, όσο ζει και το lambda (γίνεται όπως λέμε, επέκταση του χρόνου ζωής της). Τι συμβαίνει στην πραγματικότητα όταν γίνεται capture; Ας το δούμε μέσα από ένα παράδειγμα.&lt;/p&gt; &lt;p&gt;Έστω ότι έχουμε μία συνάρτηση χωρίς capturing μεταβλητών:&lt;/p&gt; &lt;p&gt;&lt;textarea name="code" class="c#"&gt;static void F() 
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = () =&amp;gt; { Console.Writeline(&amp;quot;No captured variables&amp;quot;)};
} &lt;/textarea&gt;&lt;/p&gt; &lt;p&gt;όπου:&lt;/p&gt; &lt;p&gt;&lt;textarea name="code" class="c#"&gt; public delegate void D(); &lt;/textarea&gt;&lt;/p&gt; &lt;p&gt;το delegate. &lt;/p&gt; &lt;p align="justify"&gt;O compiler αντιμετωπίζει το delegate type instantiation (με το lambda που βλέπετε εκεί), κάνοντας allocation μία πραγματική ενδιάμεση μέθοδο που έχει κάνει generate.&lt;/p&gt; &lt;p&gt;&lt;textarea name="code" class="c#"&gt;static void F()
{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = new D(generated_Method); 
}
static void generated_Method()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Writeline(&amp;quot;No captured variables&amp;quot;)
} &lt;/textarea&gt;&lt;/p&gt; &lt;p&gt;Έστω ότι το lambda κάνει capture μία τοπική μεταβλητή:&lt;/p&gt; &lt;p&gt;&lt;textarea name="code" class="c#"&gt;static void F() 
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; int y = 1;
&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = () =&amp;gt; { Console.Writeline(y)};
}&lt;/textarea&gt;&lt;/p&gt; &lt;p align="justify"&gt;H C# σε αυτό το σημείο, προσδίδει σημασιολογία closure και λέει: Επειδή το αντικείμενο που γίνεται reference από το d (η μέθοδος που κάνει Writeline το y, δηλαδή),&amp;nbsp; (μπορεί) να ζήσει περισσότερο από το scope της F (π.χ., αν επιστραφεί από τη συνάρτηση), &lt;b&gt;κρατά τη&lt;/b&gt; &lt;b&gt;μεταβλητή &lt;/b&gt;y (όχι απλά την τιμή της), για να την χρησιμοποιήσει, όταν το d γίνει invoke και εκτελεστεί. Πριν δείξουμε όμως την περίπτωση όπου το d ζει περισσότερο από το y (προς το παρόν δεν ζει) ας δείξουμε τι γίνεται σε αυτό το παράδειγμα. O compiler under the hood κάνει το εξής:&lt;/p&gt; &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;void F()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; Generated_Class_Keeping_Environment gen = new Generated_Class_Keeping_Environment();
&amp;nbsp;&amp;nbsp;&amp;nbsp; gen.y = 1;
&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = new D(gen.generated_Method);
}

class Generated_Class_Keeping_Environment
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; public int y;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void generated_Method()
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Writeline(y);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
} &lt;/textarea&gt;&lt;/p&gt; &lt;p align="justify"&gt;Ταξιδεύοντας λίγο περισσότερο στο flow, τι γίνεται αν έχω μεταβλητές σε διαφορετικά statement blocks, όπως στο παρακάτω παράδειγμα; Τότε ο compiler λειτουργεί αναλόγως. Στην παρακάτω περίπτωση, έχουμε αναφορά σε μία εξωτερική μεταβλητή (this.x)&lt;/p&gt; &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;class Top
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; int x;
&amp;nbsp;&amp;nbsp;&amp;nbsp; static void F()
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int y = 1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i =0; i&amp;lt;10;i++)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int z = i*2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = () =&amp;gt; {Console.Writeline(x+y+z);};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
} &lt;/textarea&gt;&lt;/p&gt; &lt;p align="justify"&gt;Στην παραπάνω μέθοδο F, το lambda κάνει capture μία μεταβλητή που δηλώνεται μία φορά στο this και δεν αλλάζει, μία τοπική μεταβλητή που δεν αλλάζει και μία τοπική μεταβλητή που αλλάζει συνεχώς, με κάθε iteration. O compiler θα κάνει generate δύο κλάσεις. Μία (Locals2) που θα περιέχει τη μέθοδο, την μεταβλητή Z, καθώς και αναφορά στην άλλη generated κλάση. Η δεύτερη generated κλάση (Locals1) θα έχει τη μεταβλητή y και ένα reference σε object τύπου Top οπότε η συνάρτηση F θα μετασχηματιστεί ως εξής:&lt;/p&gt; &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;void F ()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp; Locals1 locals1 = new Locals1();
&amp;nbsp;&amp;nbsp;&amp;nbsp; locals1._this = this; //H Top
&amp;nbsp;&amp;nbsp;&amp;nbsp; locals1.y = 1;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i =0; i&amp;lt;10;i++)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Locals2 locals2 = new Locals2();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; locals2.locals1 = locals1; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; locals2.z = i*2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = new D(locals2.method);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp; 
} &lt;/textarea&gt;&lt;/p&gt; &lt;p align="justify"&gt;Όπως παρατηρούμε, οι μεταβλητές που έχουν γίνει capture, ζουν τώρα πια στο heap καθώς έχουν γίνει dynamic allocated μέσα σε κλάση.&lt;/p&gt; &lt;p align="justify"&gt;Ας δούμε όμως, μία χρήση των anonymous delegates σαν κανονικά first order functions που είναι. Διαβάστε προσεκτικά τον παρακάτω κώδικα. Έστω ότι θέλω να ορίσω ThreadStart delegates. Φτιάχνω ένα array από δύο anonymous delegates μέσα στο for και αναθέτω σε κάθε ένα από τα δύο κελιά του array, από ένα anonymous delegate. Τα anonymous delegates έχουν κάνει capture δύο free variables, τις outside και inside (και allocate στο heap με τις compiler generated κλάσεις που είδαμε).&lt;/p&gt; &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;static void Main() 
{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadStart[] delegates = new ThreadStart[2]; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; int outside = 0;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i=0; i &amp;lt; 2; i++) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int inside = 0;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; delegates[ i] = delegate&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine (&amp;quot;({0},{1})&amp;quot;, 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; outside, inside); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; outside++; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inside++; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadStart first = delegates[0]; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ThreadStart second = delegates[1]; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; first(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; first(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; first(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; second(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; second(); 
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
}&lt;/textarea&gt;&lt;/p&gt; &lt;p align="justify"&gt;Σκεφτείτε ότι την ώρα που γίνεται η ανάθεση τιμής στο delegates[ i] γίνονται οι αναθέσεις, έχουν γίνει capture οι μεταβλητές και ο κώδικας εκτελείται παρακάτω. Γίνεται invoke το delegate της θέσης 0 και τυπώνει (0,0). Τη δεύτερη φορά και τα δύο αυξάνονται, όμοια και την τρίτη φορά και έχουμε (1,1) και (2,2). Τώρα εκτελείται το δεύτερο delegate. To outside είναι σε κατάσταση 3, οπότε με την αύξηση γίνεται 4, το inside όμως έχει ΞΑΝΑ-δηλωθεί (int inside = 0), οπότε το delegate έχει διαφορετικό instance της inside, αρχικοποιημένο στο 0. Οπότε η συνέχεια έπεται ως (3,0) και (4,1). Αν γράφατε τον παραπάνω κώδικα δείτε τι θα σας έδειχνε ο Resharper … ;) Πώς μπορώ να το διορθώσω αυτό, αν δεν το επιθυμώ (χωρίς να πατήσω την λάμπα αριστερά :P); &lt;/p&gt; &lt;p align="justify"&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/image_7C55840D.png"&gt;&lt;img src="http://www.studentguru.gr/blogs/grnemo/image_thumb_62ED80D3.png" style="border-width:0px;display:inline;" title="image" alt="image" border="0" height="114" width="401" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;h4&gt;Γιατί είναι τόσο σημαντικά τα closure semantics;&lt;/h4&gt; &lt;p&gt;Έστω ότι θέλουμε να φιλτράρουμε μία λίστα με βάση κάποια κριτήρια. Ας το υλοποιήσουμε απλά! Τι χρειαζόμαστε; Μία λίστα για να διαβάσουμε, έναν κανόνα που να δείχνει true αν κάνει pass το αντικείμενο και να θα το εισάγει σε μία νέα λίστα. Αφού διατρέξουμε όλη τη λίστα, θα έχουμε στα χέρια μας μία άλλη λίστα μόνο με όσα “πέρασαν”.&lt;/p&gt; &lt;p&gt;&lt;textarea name="code" class="c#"&gt;public static IList&amp;lt;T&amp;gt; FindAllItemsBasedOnPredicate&amp;lt;T&amp;gt;(IList&amp;lt;T&amp;gt; src, Predicate&amp;lt;T&amp;gt; predicate)
&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;T&amp;gt; list= new List&amp;lt;T&amp;gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (T item in src)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (predicate(item))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list.Add(item);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return list;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/textarea&gt;&lt;/p&gt;&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;Όμορφα. Προχωράμε στο filtering. Έστω ότι θέλουμε να βρούμε όλους τους πελάτες ως 18 ετών.&lt;/p&gt;
&lt;p&gt;Στη C# 3.0 (λόγω lambdas) μπορούμε να γράψουμε το εξής:&lt;/p&gt;
&lt;p&gt;&lt;textarea name="code" class="c#"&gt;Predicate&amp;lt;Customer&amp;gt; ageRule = customer =&amp;gt; customer.age &amp;lt;= 18;
IList&amp;lt;Customer&amp;gt; youngCustomers= FindAllItemsBasedOnPredicate(CustomerList, ageRule );
&lt;/textarea&gt;&lt;/p&gt;
&lt;div align="justify"&gt;
&lt;p&gt;Αν όμως δεν θέλουμε hard coded το 18 και χρειαζόμαστε να το ρυθμίζουμε μέσα από μία μεταβλητή; Έστω ότι δεν έχουμε closures. Τι κάνουμε; Το αλλάζουμε απλά με μία μεταβλητή; Και αν η μεταβλητή είναι static και αλλάξει; Και αν θέλουμε thread safety; Αν αναφερόμαστε σε Threading και θέλουμε να περάσουμε παραμέτρους στο thread μας; H C# έχει την δυνατότητα capturing μεταβλητής και όχι τιμής και αυτό είναι ένα από τα δυνατά της σημεία.&lt;/p&gt;
&lt;h4&gt;Some food for thought&lt;/h4&gt;
&lt;p&gt;Τι θα τυπώσει ο παρακάτω κώδικας χωρίς Copy-Paste-F5; ;););)&lt;/p&gt;
&lt;p&gt;&lt;textarea name="code" class="c#"&gt;delegate void Func(); 
class Program 
{ 
&amp;nbsp;&amp;nbsp;&amp;nbsp; static Func[] functionArray = new Func[10]; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; static void FillFunctionArray(int count) 
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; count; i++) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; functionArray[ i] = () =&amp;gt; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Write(&amp;quot;{0} &amp;quot;, i); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }; 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main(string[] args) 
&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FillFunctionArray(functionArray.Length); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; functionArray.Length; i++) 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; functionArray[ i](); 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.ReadKey();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
} &lt;/textarea&gt;
&lt;/p&gt;&lt;p&gt;Enjoy closures!!!&lt;/p&gt;
&lt;p&gt;Για όσους ενδιαφέρονται να διαβάσουν μία ιδέα για το πώς μπορεί να επεκταθεί η IL για να υποστηρίζονται closures και άλλα όμορφα πράγματα σε επίπεδο IL, μπορούν να διαβάσουν μία σχετική δημοσίευση από MSR του Don Syme, δημιουργού της F#.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;D. Syme, “ILX: Extending the. NET Common IL for Functional Language Interoperability,” Electronic Notes in Theoretical Computer Science 59, no. 1 (2001): 53–72. &lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Closures στη C#&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2010/03/09/closures-c.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Closures στη C#";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2010/03/09/closures-c.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=110972" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="C#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/.NET/default.aspx" /><category term="delegates" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/delegates/default.aspx" /><category term="lambdas" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/lambdas/default.aspx" /><category term="closures" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/closures/default.aspx" /></entry><entry><title>Αντιγραφή αρχείου σε UNC Path προγραμματιστικά (ASP.NET or just code)</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2010/01/14/unc-path-asp-net-amp-code.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2010/01/14/unc-path-asp-net-amp-code.aspx</id><published>2010-01-14T21:02:24Z</published><updated>2010-01-14T21:02:24Z</updated><content type="html">&lt;p align="justify"&gt;Η αντιγραφή αρχείου σε NAS, προγραμματιστικά (ή εν γένει σε κάποιο UNC location εκτός τοπικού μηχανήματος) είναι μία ανάλογη διαδικασία, όπως αν το κάνουμε μέσω του UI. Θα ανοίγαμε το Run, στην συνέχεια πληκτρολογούμε το unc path. Αν σε εκείνη την τοποθεσία έχουν τεθεί permissions για όλους, τότε το παράθυρο ανοίγει κατευθείαν. Σε αντίθετη περίπτωση θα πρέπει να εισαχθούν τα στοιχεία για να γίνει login ο χρήστης, είτε τοπικός, είτε domain (σε αυτήν την περίπτωση θα πρέπει να εισαχθεί και το domain με τον γνωστό τρόπο domain/username). Τι χρειάζεται όμως για να γίνει προγραμματιστικά η διεργασία και μάλιστα μέσα από κώδικα που εκτελείται στο περιβάλλον του IIS; Τότε αυτό που θέλουμε να κάνουμε λέγεται delegation και υπόκειται στο κεφάλαιο &lt;a href="http://msdn.microsoft.com/en-us/library/aa291350%28VS.71%29.aspx" target="_blank"&gt;ASP.NET Delegation&lt;/a&gt;. Με βάση αυτό μπορεί η ASP.NET να προσπελάσει resources σε απομακρυσμένο σύστημα. Μία ειδική περίπτωση αυτού είναι το &lt;a href="http://msdn.microsoft.com/en-us/library/aa292118%28VS.71%29.aspx" target="_blank"&gt;ASP.NET Impersonation&lt;/a&gt; με το οποίο το σύστημα είναι τοπικό. Mε αυτόν τον τρόπο οι ASP.NET εφαρμογές μπορούν να εκτελέσουν κώδικα κάτω από την ταυτότητα του χρήστη τον οποίο απαιτείται να χρησιμοποιήσουν για την πρόσβαση. Για να γίνει αυτό θα πρέπει τα δύο μηχανήματα να μελετηθούν ως προς το λειτουργικό τους, την ύπαρξη του δικαιώματος για delegation, κτλ. Επίσης θέλει προσοχή κατά το σχεδιασμό μιάς τέτοιας λύσης για λόγους ασφαλείας.&lt;/p&gt;  &lt;p align="justify"&gt;Έστω ότι έχω την περίπτωση που ο IIS τρέχει κάτω από το IUSR_&lt;i&gt;machinename&lt;/i&gt; για ανώνυμη πρόσβαση. Αν γνωρίζω από πριν username και password τότε μπορώ ρυθμίζοντας το directive &amp;lt;processModel&amp;gt; να ελέγξω την παραπάνω διαδικασία (βλ. link για asp.net delegation). Στην περίπτωσή μου θέλω να ελέγχω την διαδικασία πλήρως χρησιμοποιώντας το LogonUser API. Θέλω λοιπόν να κάνω ένα συγκεκριμένο account login, όπως έδειξα και νωρίτερα όταν ήθελα να μεταφέρω ένα αρχείο από το ui. Δεν υπάρχει αντίστοιχη μέθοδος όμως (ως Login, αυτούσια), στο .ΝΕΤ και η μόνη μέθοδος που κάνει impersonate είναι η WindowsIdentity.Impersonate (IntPtr), από το &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.principal.aspx"&gt;System.Security.Principal&lt;/a&gt;. Τι είναι το IntPtr; Είναι ένα handle για τον χρήστη του συστήματος και ανακτάται από κλήση σε unmanaged κώδικα μέσω της &lt;strong&gt;LogonUser&lt;/strong&gt; από το advapi32.dll.&lt;/p&gt;  &lt;p align="justify"&gt;Στον κώδικά μου ήθελα να μπορώ να τρέχω ένα File.Copy (ή οτιδήποτε) το οποίο θα εκτελείται με βάση συγκεκριμένα credentials.&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;Impersonation.Execute(myEntity.NasUser, myEntity.NasPassword, () =&amp;gt;    
{     
//Copy File to NAS     
&amp;#160;&amp;#160; File.Copy(sourceFile, Path.Combine(myEntity.UploadPath, Path.GetFileName(sourceFile)), true);     
});&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;#region DllImport    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [DllImport(&amp;quot;advapi32.dll&amp;quot;, SetLastError = true)]     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public static extern bool LogonUser(     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string lpszUsername,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string lpszDomain,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; string lpszPassword,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int dwLogonType,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int dwLogonProvider,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; out IntPtr phToken     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; );    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [DllImport(&amp;quot;kernel32.dll&amp;quot;, CharSet = CharSet.Auto)]     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; public extern static bool CloseHandle(IntPtr handle);     
#endregion&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Έτσι η Execute που έγραψα, χοντρικά ήταν η εξής &lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;public static void Execute(string userName, string domain, string password, Action action)    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; try     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bool bImpersonated = LogonUser(     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; userName,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; domain,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; password,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; logon32LogonInteractive,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; logon32ProviderDefault,     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; out tokenHandle);     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (bImpersonated == false)     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new Win32Exception(Marshal.GetLastWin32Error());     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; WindowsIdentity newId = new WindowsIdentity(tokenHandle);     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; impersonatedUser = newId.Impersonate();     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; action();     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; catch (Exception ex)     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw ex;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; finally     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (impersonation != null)     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; impersonation.Dispose();     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;Αξίζει να σημειώσουμε ότι στο τέλος θα πρέπει οπωσδήποτε να επαναφέρεται το process identity στο προηγούμενο (μέσω τη undo), γιατί θα υπάρξει πρόβλημα στις περαιτέρω ενέργειες&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;public void Dispose()    
{     
&amp;#160;&amp;#160;&amp;#160; // Stop impersonating the user.     
&amp;#160;&amp;#160;&amp;#160; if (impersonatedUser != null)     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; impersonatedUser.Undo();     
&amp;#160;&amp;#160;&amp;#160; // close handle     
&amp;#160;&amp;#160;&amp;#160; if (tokenHandle != IntPtr.Zero)     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CloseHandle(tokenHandle);     
}&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;Τέλος η παραπάνω διεργασία χρειάζεται full trust (PermissionSetAttribute)&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Αντιγραφή αρχείου σε UNC Path προγραμματιστικά (ASP.NET or just code)&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2010/01/14/unc-path-asp-net-amp-code.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Αντιγραφή αρχείου σε UNC Path προγραμματιστικά (ASP.NET or just code)";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2010/01/14/unc-path-asp-net-amp-code.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=109877" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="C#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/.NET/default.aspx" /><category term="ASP.NET" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/ASP.NET/default.aspx" /></entry><entry><title>Παρουσίαση .NET και C# στο ΠΜΣ Πληροφοριακά Συστήματα ΟΠΑ – Τεχνολογία Λογισμικού</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2010/01/12/net-c.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2010/01/12/net-c.aspx</id><published>2010-01-12T14:43:29Z</published><updated>2010-01-12T14:43:29Z</updated><content type="html">&lt;p align="justify"&gt;Παραθέτω το υλικό της σημερινής παρουσίασης για .NET, C# που είδαμε στο μάθημα Τεχνολογίας Λογισμικού (ευχαριστούμε τον καθηγητή Εμ. Γιακουμάκη που την πραγματοποιήσαμε επιτυχώς). Η παρουσίαση που διαδέχτηκε τη δική μου, από τον Μιχάλη Ζερβό, βρίσκεται &lt;a href="http://www.studentguru.gr/blogs/jupiter/archive/2010/01/12/web-services-wcf.aspx" target="_blank"&gt;εδώ&lt;/a&gt;. Και οι δύο, βρίσκονται στο e-class του μαθήματος. &lt;/p&gt;  &lt;p align="justify"&gt;Στην παρουσίασή μου, προσπάθησα να δώσω όσες περισσότερες ιδέες μπορούσα (στο σύντομο χρονικό διάστημα της μίας ώρας) αναδεικνύοντας την εκφραστικότητά της και τις δυνατότητες που έχει. Καλύφθηκαν αρκετά θέματα, ξεκινώντας από τις βασικές δομές και εξηγώντας στη συνέχεια μία πληθώρα από άλλες όπως, delegates, anonymous functions, anonymous types, iterators, lambdas, extension methods, LINQ καθώς επίσης τα βασικά από τη λειτουργία του ίδιου του περιβάλλοντος εκτέλεσης και της εσωτερικής οργάνωσης του .NET. H παρουσίαση, είχε στόχο να δώσει πολλές ιδέες και ερεθίσματα, καθώς δύσκολα μία έννοια μπορεί να διατυπωθεί μέσα από μερικά slides σε περιορισμένο χρόνο. &lt;/p&gt;  &lt;p align="justify"&gt;Τα Demos (WPF, F#) που παρουσίασα για τις ανάγκες περιήγησης στο Visual Studio βρίσκονται &lt;a href="http://www.studentguru.gr/blogs/grnemo/Demos.rar" target="_blank"&gt;εδώ&lt;/a&gt;, καθώς και η &lt;a href="http://www.studentguru.gr/blogs/grnemo/CSharpdotNETpresentationAggelosMpimpoudis.pdf" target="_blank"&gt;παρουσίαση&lt;/a&gt;. Για να κατεβάσετε την Beta 2 του &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx"&gt;VS Studio 2010 Beta 2&lt;/a&gt; θα ακολουθήσετε τον εν λόγω σύνδεσμο. Τέλος, για την σύντομη αναφορά στην F#, μπορείτε να δείτε μία επεξήγηση (στο ίδιο πρόγραμμα για τους πύργους του Ανόι) στο εξής &lt;a href="http://www.studentguru.gr/blogs/grnemo/archive/2009/12/13/f.aspx" target="_blank"&gt;blogpost&lt;/a&gt;.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Enjoy coding!!&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Παρουσίαση .NET και C# στο ΠΜΣ Πληροφοριακά Συστήματα ΟΠΑ – Τεχνολογία Λογισμικού&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2010/01/12/net-c.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Παρουσίαση .NET και C# στο ΠΜΣ Πληροφοριακά Συστήματα ΟΠΑ – Τεχνολογία Λογισμικού";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2010/01/12/net-c.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=109845" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="C#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/.NET/default.aspx" /><category term="Visual Studio 2010" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/Visual+Studio+2010/default.aspx" /><category term="F#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/F_2300_/default.aspx" /></entry><entry><title>Πύργοι του Ανόι σε F#</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/12/13/f.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/12/13/f.aspx</id><published>2009-12-13T14:22:00Z</published><updated>2009-12-13T14:22:00Z</updated><content type="html">&lt;p align="justify"&gt;Θυμάστε πώς είχαμε υλοποιήσει τους &lt;a href="http://en.wikipedia.org/wiki/Tower_of_Hanoi" target="_blank"&gt;πύργους του Ανόι&lt;/a&gt; σε C στη σχολή όταν πρωτοπήγαμε; Ορίστε πόσο απλή είναι η έκδοση του σε συναρτησιακό προγραμματισμό (με χρήση της &lt;a href="http://en.wikipedia.org/wiki/F_Sharp_%28programming_language%29" target="_blank"&gt;F#&lt;/a&gt;).&lt;/p&gt;  &lt;p align="justify"&gt;Κατ’αρχάς μερικές νύξεις στο VS Studio 2010 που έχει ενσωματωμένα templates και debugging tools για αυτή τη νέα γλώσσα. Ανοίγουμε το &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx" target="_blank"&gt;VS Studio 2010 Beta 2&lt;/a&gt; που μπορούμε να το κατεβάσουμε δωρεάν όσο διαρκεί η φάση Beta και διαλέγουμε να δημιουργήσουμε ένα Console Application σε F#.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/image_4FBFC7B8.png"&gt;&lt;img src="http://www.studentguru.gr/blogs/grnemo/image_thumb_7A1BD308.png" style="border-width:0px;display:inline;" title="image" alt="image" border="0" height="146" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p align="justify"&gt;Στην συνέχεια κάνουμε paste τον παρακάτω κώδικα (προσέξτε το &lt;a href="http://msdn.microsoft.com/en-us/library/dd233191%28VS.100%29.aspx" target="_blank"&gt;indentation&lt;/a&gt; στον κώδικα καθώς έχει σημασία να είναι σωστά στοιχειοθετημένες οι εντολές. Δεν γίνεται compile αν δεν ακολουθηθούν οι αντίστοιχοι απλοί κανόνες) που ορίζει δύο συναρτήσεις, την move (μετακίνησε από στύλο σε στύλο, στην ουσία απλά κάνει print την κίνηση για να βλέπουμε την αλλαγή της κατάστασης) και την hanoi η οποία υλοποιεί την αναδρομική συνάρτηση. Όποτε δοκιμάζω να μάθω την F#, μου αρέσει να στέλνω ότι γράφω στο interactive environment της. Ότι γράφεται σε αυτό το παράθυρο μοιάζει να περνάει από interpreter, αλλά στην ουσία γίνεται δυναμικά compile on-the-fly βλέποντας την αποτίμηση κάποιας έκφρασης, εκείνη τη στιγμή στο παράθυρο.&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;let move = printfn &amp;quot;Μετακίνησε δίσκο από %c στο %c&amp;quot;    
let rec hanoi f x t = function     
&amp;nbsp; | 1 -&amp;gt; move f t     
&amp;nbsp; | n -&amp;gt; hanoi f t x (n - 1)     
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; move f t     
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hanoi x f t (n - 1)&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;Το παραπάνω κομμάτι κώδικα ορίζει μία απλή συνάρτηση και μία αναδρομική.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/image_1819E0FD.png"&gt;&lt;img src="http://www.studentguru.gr/blogs/grnemo/image_thumb_48803FA6.png" style="border-width:0px;margin:0px 20px 0px 0px;display:inline;" title="image" alt="image" align="left" border="0" height="244" width="184" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Μόλις γίνει η μεταφορά του κώδικα στο interactive παράθυρο, μας παρουσιάζονται δύο γραμμές:&lt;/p&gt;  &lt;p&gt;val move : (char -&amp;gt; char -&amp;gt; unit)&lt;/p&gt;  &lt;p&gt;&lt;strike&gt;//Η δήλωση της move που παίρνει δύο παραμέτρους τύπου char&lt;/strike&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;//Η παραπάνω δήλωση ερμηνεύεται ως εξής λόγω του &lt;a href="http://en.wikipedia.org/wiki/Currying"&gt;currying&lt;/a&gt;: το move είναι μία συνάρτηση που παίρνει ένα argument και επιστρέφει μία συνάρτηση με τύπο (char-&amp;gt;unit). &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;val hanoi : char -&amp;gt; char -&amp;gt; char -&amp;gt; int –&amp;gt; unit&lt;/p&gt;  &lt;p&gt;&lt;strike&gt;//Η δήλωση της hanoi που παίρνει τρεις χαρακτήρες και ένας ακέραιο.&lt;/strike&gt;&lt;/p&gt;&lt;p&gt;//Ομοιοτρόπως και σε αυτή τη δήλωση. To int σε αυτή τη περίπτωση είναι μία επίδραση του keyword function, το οποίο λόγω της ιδιότητάς του δημιουργεί μία έμμεση μεταβλητή. &lt;/p&gt;  &lt;p align="justify"&gt;Η δήλωση unit σημαίνει ότι δεν επιστρέφεται τίποτα από αυτή τη συνάρτηση. Το unit αποτελεί έναν &lt;a href="http://msdn.microsoft.com/en-us/library/dd233210%28VS.100%29.aspx" target="_blank"&gt;primitive type&lt;/a&gt; που δεν περιέχει καμία απολύτως πληροφορία και η μόνη του τιμή είναι το (). &lt;/p&gt;  &lt;p align="justify"&gt;Πάμε στην αναδρομική συνάρτηση. Ξεκινάμε με το keyword &lt;a href="http://msdn.microsoft.com/en-us/library/dd233238%28VS.100%29.aspx" target="_blank"&gt;let&lt;/a&gt;, με το οποίο δηλώνουμε πως ότι θα γράψουμε, θα δεθεί με το όνομα hanoi, γίνεται δηλαδή binding του ονόματος με την έκφραση της συνάρτησης. Στη συνέχεια, με το keyword rec αναφέρουμε πως το binding αυτό μπορεί να αναφερθεί στον εαυτό του ή πιο απλά, ότι έχουμε μία αναδρομική συνάρτηση. Ορίζονται το όνομα και οι μεταβλητές μας (χωρίς να ορίζουμε τύπο-γίνεται infer από την F#). Με την λέξη κλειδί &lt;i&gt;function&lt;/i&gt; ανακοινώνουμε ότι έχουμε μία συνάρτηση η οποία μπορεί να αναγνωρίσει πρότυπα πάνω στα ορίσματά της (pattern matching), έτσι η F# καταλαβαίνει ότι στα ορίσματα υπεισέρχεται ακόμα ένας τύπος ακεραίου (o ακέραιος εκείνος που μας έδειξε το interactive window παραπάνω). Τι είναι pattern matching εν συντομία; Pattern matching είναι η δυνατότητα που προσφέρει η δομή function… και η δομή match…with… να εκτιμά το αποτέλεσμα μίας έκφρασης και να συγκρίνει αυτό το αποτέλεσμα με μία σειρά από κανόνες. Στην περίπτωσή μας, οι κανόνες πηγάζουν από την αναδρομική λύση του προβλήματος. Αν παρατηρήσουμε τη μαθηματική λύση και το παραπάνω κώδικα, θα δούμε ότι οι παραπάνω εκφράσεις είναι η μετάφραση της μαθηματικής λύσης αυτούσια από το συλλογισμό μας, στην F#. Παρατηρήστε την &lt;a href="http://en.wikipedia.org/wiki/Tower_of_Hanoi#Recursive_solution" target="_blank"&gt;αναδρομική λύση&lt;/a&gt; του προβλήματος. Έχει τρία βήματα που λένε:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;- Μετέφερε n-1 δίσκους από τον πρώτο στύλο στο δεύτερο (οπότε απομένει ο δίσκος με τον αριθμό n – ο μεγαλύτερος στον πρώτο στύλο)      &lt;br /&gt;- Μετέφερε τον δίσκο n από τον πρώτο στύλο στον τρίτο       &lt;br /&gt;- Μετέφερε n-1 δίσκους από τον δεύτερο στύλο στον τρίτο. &lt;/li&gt;    &lt;li&gt;- Τι γίνεται όταν έχουμε τον δίσκο υπ’ αριθμόν 1 (τον μικρότερο δηλαδή); Μετέφερέ τον στον τρίτο στύλο! &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Ακριβώς δηλαδή ότι είναι γραμμένο στο παραπάνω κομμάτι κώδικα!&lt;/p&gt;  &lt;p align="justify"&gt;Εκτελώντας τον κώδικα για διαφoρετικούς ακεραίους, μία για 2 δίσκους και μία για 4 δίσκους, βλέπουμε τη λύση στο interactive window.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/image_2DD3A38D.png"&gt;&lt;img src="http://www.studentguru.gr/blogs/grnemo/image_thumb_713BA4EF.png" style="border-width:0px;display:inline;" title="image" alt="image" border="0" height="264" width="189" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Cheers!&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Πύργοι του Ανόι σε F#&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/12/13/f.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Πύργοι του Ανόι σε F#";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/12/13/f.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=109224" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term=".NET" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/.NET/default.aspx" /><category term="Visual Studio 2010" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/Visual+Studio+2010/default.aspx" /><category term="F#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/F_2300_/default.aspx" /></entry><entry><title>Εισαγωγή στα Expression Trees και στις δυναμικές μεθόδους (Visual Studio 2010)</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/11/28/expression-trees-visual-studio-2010.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/11/28/expression-trees-visual-studio-2010.aspx</id><published>2009-11-28T02:29:03Z</published><updated>2009-11-28T02:29:03Z</updated><content type="html">&lt;p align="justify"&gt;Στο απόλυτο βιβλίο για &lt;a href="http://www.amazon.co.uk/Compilers-Principles-Techniques-Alfred-Aho/dp/0321491696/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1259361105&amp;amp;sr=8-1" target="_blank"&gt;compilers&lt;/a&gt; (καθιερωμένο ως Dragon Book εξαιτίας του concept art εξωφύλλου του στην πρώτη έκδοση) ως abtract syntax trees ή απλά syntax trees, ορίζονται οι ιεραρχικές συντακτικές δομές του πηγαίου κώδικα ενός προγράμματος. Όταν γράφουμε κώδικα, υπάρχει μία πάρα πολύ συγκεκριμένη διαδικασία η οποία μετατρέπει τις λέξεις και τα σύμβολα που γράφουμε, σε δομές που έχουν συγκεκριμένη σημασιολογία. Το πρώτο κομμάτι ενός μεταγλωττιστή ασχολείται με το “διάβασμα” του κώδικα που γράφουμε. Αυτή η διαδικασία αποτελείται από τρία στάδια. Στο πρώτο στάδιο υπάρχει ένας λεκτικός αναλυτής ο οποίος παίρνει ως είσοδο το αρχείο κειμένου που γράψαμε, και το σπάει σε τεμάχια ή αλλιώς tokens. Για παράδειγμα εμείς γράφουμε items + 1 και ο αναλυτής αναγνωρίζει ως token την λέξη item. Στην συνέχεια λαμβάνει χώρα η ανάλυση (parsing), που παίρνει τα tokens και σύμφωνα με τους κανόνες της γλώσσας, δημιουργεί συντακτικά δένδρα εκφράσεων. Στο τελευταίο βήμα λαμβάνονται οι εν λόγω δενδρικές δομές και παράγεται αυτό που λέμε ενδιάμεσος κώδικας. Υπάρχουν δύο ήδη συντακτικών δένδρων, τα αφηρημένα και τα μη (abstract και concrete). Σε ένα abstract syntax tree λοιπόν απεικονίζεται μία έκφραση, του οποίου ο εσωτερικός κόμβος είναι ένας operator και τα παιδιά είναι τα operands (τα οποία μπορούν με τη σειρά τους να είναι εκφράσεις). Η διαφορά με τα &lt;a href="http://en.wikipedia.org/wiki/Concrete_syntax_tree" target="_blank"&gt;concrete syntax trees&lt;/a&gt; είναι ότι τα concrete έρχονται κατευθείαν από τον parser (αντικατοπτρίζοντας αποκλειστικά το συντακτικό της γλώσσας) ενώ τα abstract προσδίδουν με τη σειρά τους πρόσθετη πληροφορία (σχετικά με σημασιολογία π.χ.).&lt;/p&gt;  &lt;p align="justify"&gt;Πολύ όμορφα λοιπόν, γράφουμε λέξεις περιγράφοντας διαδικασίες οι οποίες μεταφράζονται σε εντολές. Στην γλώσσα C# τα &lt;a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx" target="_blank"&gt;expression trees&lt;/a&gt; αποτελούν έναν τύπο δεδομένων που αποθηκεύει κώδικα σε μορφή δεδομένων. Τα δεδομένα αποθηκεύονται υπό τη μορφή δένδρων, όπως ακριβώς τα δένδρα που περιέγραψα παραπάνω. Με το συγκεκριμένο τύπο δεδομένων μπορούμε να κάνουμε κάτι πάρα πολύ όμορφο και θεάρεστο :P: να αλλάξουμε ή να μετασχηματίσουμε κώδικα κατά το runtime execution, πριν τον εκτελέσουμε. Για παράδειγμα υπάρχει η δυνατότητα να μετατραπεί κώδικας C# (όπως κάνει η LINQ μέσω των &lt;a href="http://msdn.microsoft.com/en-us/library/bb397676.aspx" target="_blank"&gt;query expressions&lt;/a&gt;) σε κώδικα που εκτελείται σε άλλο process, όπως είναι μία βάση δεδομένων. &lt;/p&gt;  &lt;p align="justify"&gt;Έστω ότι έχουμε την παρακάτω έκφραση lambda λοιπόν, η οποία μας περιγράφει μία &lt;a href="http://msdn.microsoft.com/en-us/library/bb534647.aspx" target="_blank"&gt;συνάρτηση&lt;/a&gt; που παίρνει δύο ακεραίους ως παραμέτρους και επιστρέφει έναν άλλον ακέραιο. &lt;/p&gt;  &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt; Func&amp;lt;int, int, int&amp;gt; function = (a,b) =&amp;gt; a + b; &lt;/textarea&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Το παραπάνω μας βοηθάει να δηλώσουμε μία μεταβλητή συνάρτησης στην οποία αποθηκεύεται ένα lambda που υπολογίζει το άθροισμα δύο αριθμών (βλ. &lt;a href="http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx" target="_blank"&gt;delegates&lt;/a&gt; και &lt;a href="http://msdn.microsoft.com/en-us/library/twcad0zb(VS.80).aspx" target="_blank"&gt;generic functions&lt;/a&gt;). Ακόμα και για κάποιον που δεν έχει κατανοήσει πολύ καλά τις δύο παραπάνω έννοιες, φαίνεται πολύ καθαρά από την παραπάνω γραμμή ότι κατά κάποιον τρόπο έχουμε αποθηκεύσει στη μεταβλητή function μία αναφορά προς εκτελέσιμο κώδικα. Τα expression trees &lt;u&gt;δεν&lt;/u&gt; είναι εκτελέσιμος κώδικας, οπότε πώς μεταφράζουμε το παραπάνω expression σε expression tree;&lt;/p&gt;  &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;Expression&amp;lt;Func&amp;lt;int, int, int&amp;gt;&amp;gt; expression = (a,b) =&amp;gt; a + b;&lt;/textarea&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Με την παραπάνω γραμμή κάναμε αυτό που θέλαμε! Δηλώσαμε μία μεταβλητή expression η οποία περιέχει σε μορφή δεδομένων το συντακτικό δένδρο που θέλαμε. Τι μπορούμε να κάνουμε με αυτό λοιπόν; Μπορούμε καταρχάς να πάρουμε το σώμα της συνάρτησης με το Property Body, τις παραμέτρους με το Property Parameter, τον τύπο του κόμβου που θέλουμε με το Property NodeType (&lt;a href="http://msdn.microsoft.com/en-us/library/bb361179.aspx" target="_blank"&gt;η λίστα με τους τύπους expressions&lt;/a&gt;), ή απλά τον CLR τύπο με το Property Type. Για την καλύτερη κατανόηση της διαφοράς μεταξύ Node Type και Type παραθέτω το &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.type.aspx" target="_blank"&gt;παράδειγμα&lt;/a&gt; από το msdn:&lt;/p&gt;  &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;// NodeType is Constant; Type is System.Int32.&amp;#160; 
ConstantExpression constExpr1 = Expression.Constant(5);&amp;#160; 
// NodeType is Add; Type is System.Int32    
BinaryExpression binExpr = Expression.Add(constExpr1, constExpr1)&lt;/textarea&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Έστω ότι έχουμε το expression που περιγράψαμε παραπάνω: Τα “δεδομένα” μπορούν να ανακτηθούν ως εξής:&lt;/p&gt;  &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;BinaryExpression body = (BinaryExpression)expression.Body;   
ParameterExpression left = (ParameterExpression)body.Left;     
ParameterExpression right = (ParameterExpression)body.Right;&lt;/textarea&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Τι κάνουμε όμως αν έχουμε μία έκφραση σε μορφή δεδομένων και θέλουμε να την εκτελέσουμε; Ότι κάνουμε πάντα! Compile!&lt;/p&gt;  &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;expression.Compile()(3, 5);&lt;/textarea&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Μπορεί με πρώτη ματιά να φαίνεται ότι απλά προσθέσαμε overhead στην λειτουργικότητα των lambdas. Σκεφτείτε όμως μία χρήση που ήδη βλέπετε τριγύρω σας. Πόσα διαφορετικά είδη LINQ εκτός από LINQ to objects υπάρχουν; Πώς τα queries που γράφουμε, μπορούν να εκτελεστούν σε διαφορετικά processes που τρέχουν κάποια εφαρμογή; Μέχρι τώρα λοιπόν, αυτή είναι η αλήθεια για την κύρια χρήση των expression trees. Χρησιμοποιούνται σε LINQ providers καθώς επίσης και σε μετατροπές expression trees και compilation. Στο Visual Studio 2010 τα Expression Trees έχουν επεκταθεί και κάποιος προγραμματιστής μπορεί τώρα πια με τη χρήση τους, να παράγει και δυναμικές μεθόδους (χωρίς MSIL). Αυτή η νέα δυνατότητα δεν μπορεί να πραγματοποιηθεί με lambda expressions αλλά μόνο με το νεό Expression Trees APΙ (διαθέσιμο στο Visual Studio 2010 έχοντας διατηρήσει και το υπάρχον functionality) που το επιτρέπει αυτό. Ας ξεκινήσουμε με την &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.block%28VS.100%29.aspx" target="_blank"&gt;Expression.Block&lt;/a&gt; που συμβάλει στις νέες δυνατότητες των Expression Trees και επιτρέπει σειριακή εκτέλεση expressions. Το παράδειγμα πηγάζει από &lt;a href="http://blogs.msdn.com/csharpfaq/archive/2009/09/14/generating-dynamic-methods-with-expression-trees-in-visual-studio-2010.aspx" target="_blank"&gt;εδώ&lt;/a&gt;: &lt;/p&gt;  &lt;p align="justify"&gt;&lt;textarea name="code" class="c#"&gt;  // Δημιουργώ ένα expression που θα κρατήσει την παράμετρο int arg    
ParameterExpression param = Expression.Parameter(typeof(int), &amp;quot;arg&amp;quot;);     
// Δημιουργώ ένα expression που τυπώνει ένα string     
MethodCallExpression firstMethodCall = Expression.Call(     
&amp;#160;&amp;#160;&amp;#160; typeof(Console).GetMethod(&amp;quot;WriteLine&amp;quot;, new Type[] { typeof(String) }),     
&amp;#160;&amp;#160;&amp;#160; Expression.Constant(&amp;quot;Print arg:&amp;quot;));     
// Δημιουργώ ένα expression που τυπώνει την τιμή της παραμέτρου param (int arg)     
MethodCallExpression secondMethodCall = Expression.Call(     
&amp;#160;&amp;#160;&amp;#160; typeof(Console).GetMethod(&amp;quot;WriteLine&amp;quot;, new Type[] { typeof(int) }),     
&amp;#160;&amp;#160;&amp;#160; param);     
// Βάζω σε σειρά εκτέλεσης τα δύο expressions     
BlockExpression block = Expression.Block(firstMethodCall, secondMethodCall);     
// Compiling ένα lambda κλείνοντας τον τύπο μεθόδου     
// ως μία μέθοδο που παίρνει μία παράμετρο το οποίο lambda     
// γίνεται construct με το προηγούμενο block ένα πίνακα     
// με τις παραμέτρους και την αποτίμηση τους στην παράμετρο του lambda     
Expression.Lambda&amp;lt;Action&amp;lt;int&amp;gt;&amp;gt;(block,new ParameterExpression[] { param }).Compile()(10);     
Console.ReadKey();  &lt;/textarea&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Το αποτέλεσμα έχει ως εξής:&lt;/p&gt;  &lt;p align="justify"&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/image_2F6D70E7.png"&gt;&lt;img style="border-right-width:0px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;margin-left:auto;border-left-width:0px;margin-right:auto;" title="image" border="0" alt="image" src="http://www.studentguru.gr/blogs/grnemo/image_thumb_31E67CD8.png" width="679" height="354" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p align="justify"&gt;Στο ίδιο blog post μπορούμε να βρούμε ένα πιο δύσκολο παράδειγμα, παρουσιάζοντας πώς μπορούμε δυναμικά να φτιάξουμε μία μέθοδο που να παίρνει ως όρισμα έναν αριθμό (&lt;a href="http://msdn.microsoft.com/en-us/library/bb355908.aspx" target="_blank"&gt;Expression.Parameter&lt;/a&gt;), να δηλώσουμε μία μεταβλητή (&lt;a href="http://msdn.microsoft.com/en-us/library/dd268005%28VS.100%29.aspx" target="_blank"&gt;Expression.Assign&lt;/a&gt;) και ένα επαναληπτικό block (&lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.loop%28VS.100%29.aspx" target="_blank"&gt;Expression.Loop&lt;/a&gt;), φτιάχνοντας την &lt;a href="http://en.wikipedia.org/wiki/Factorial" target="_blank"&gt;Factorial&lt;/a&gt;.&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Εισαγωγή στα Expression Trees και στις δυναμικές μεθόδους (Visual Studio 2010)&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/11/28/expression-trees-visual-studio-2010.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Εισαγωγή στα Expression Trees και στις δυναμικές μεθόδους (Visual Studio 2010)";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/11/28/expression-trees-visual-studio-2010.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=108771" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="C#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/C_2300_/default.aspx" /><category term="Visual Studio 2010" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/Visual+Studio+2010/default.aspx" /></entry><entry><title>1st Architecture Days post-event comments</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/10/23/1st-architecture-days-post-event-comments.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/10/23/1st-architecture-days-post-event-comments.aspx</id><published>2009-10-22T23:14:27Z</published><updated>2009-10-22T23:14:27Z</updated><content type="html">&lt;p&gt;Πριν μερικές ώρες γύρισα από το πολυαναμενόμενο event του dotnetzone.gr, για αρχιτεκτονική λογισμικού [&lt;a href="http://www.dotnetzone.gr/cs/forums/thread/54446.aspx" target="_blank"&gt;link&lt;/a&gt;]. Θα ήθελα να συγχαρώ τους διοργανωτές για την οργάνωση και τη θεματολογία. Δυστυχώς έπρεπε να αποχωρήσω στο τελευταίο μέρος λόγω υποχρεώσεων αλλά θα ήθελα να σας μεταφέρω την εμπειρία από τα τρία πρώτα μέρη.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;strong&gt;Locating and addressing performance issues: From software to hardware architecture&lt;em&gt; &lt;/em&gt;- Διομήδης Σπινέλλης&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/22102009103_2A0FF280.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="22102009103" border="0" alt="22102009103" src="http://www.studentguru.gr/blogs/grnemo/22102009103_thumb_5507E085.jpg" width="244" height="184" /&gt;&lt;/a&gt; &lt;a href="http://www.studentguru.gr/blogs/grnemo/22102009104_3B33AA56.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="22102009104" border="0" alt="22102009104" src="http://www.studentguru.gr/blogs/grnemo/22102009104_thumb_188F6BDB.jpg" width="244" height="184" /&gt;&lt;/a&gt; &lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Ο κύριος Διομήδης Σπινέλλης, μέσα σε μία ώρα έθιξε τα κύρια σημεία του code quality, και τρόπους και αρχές για ελέγχο του κώδικά μας, με στόχο την (ποιότητα)=&amp;gt;ταχύτητα, ασφάλεια, εξοικονόμηση. Οι πρακτικές και έννοιες πήγασαν από την δική του εμπειρία και μεθοδολογία, που εύκολα ένας συνειδητοποιημένος ακροατής, αν κρατήσει τις ιδέες και τις υλοποιήσει με τα δικά του εργαλεία και συστήματα, σίγουρα θα κάνει πολλά βήματα εμπρός σε οποιαδήποτε πλατφόρμα και αν εργάζεται. Η παρουσίαση πλούσια σε εικόνες, κώδικα, shell, profiling and more! Αριστούργημα.&lt;/p&gt;  &lt;p&gt;Συνοπτικά ο δεκάλογος που μου έμεινε:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Ανάλυση του προβλήματος σε επίπεδο απασχόλησης CPU-&amp;gt; user time vs system time vs idling vs clock time (procmonitor and more) &lt;/li&gt;    &lt;li&gt;Ανάλυση κώδικα με γραφήματα εξαρτήσεων στον κώδικα, flags στους compilers για πλήρες reporting μέχρι και σε επίπεδο γραμμής πηγαίου &lt;/li&gt;    &lt;li&gt;Βελτιστοποίηση αλγορίθμων με σύνεση. Εντοπισμός lower + upper bounds + reusability καλών βιβλιοθηκών + προσαρμογή στα δεδομένα μας &lt;/li&gt;    &lt;li&gt;Γνώση των εσωτερικών μηχανισμών με μετρητές απόδοσης σε επίπεδο cpu, με διαιρέσεις δεικτών με πλούσια σημασιολογία (Διαίρεση δείκτη 1/ δείκτη 2 := π.χ. utilization κάποιου πόρου χ =&amp;gt; συμπέρασμα) &lt;/li&gt;    &lt;li&gt;Προσοχή στα ΙΟ&amp;#160; (μνήμη, ιεραρχίες, locality of reference) &lt;/li&gt;    &lt;li&gt;Αποφυγή ΛΣ και κλήσεων σε αυτό &lt;/li&gt;    &lt;li&gt;Background processing + thrashing =&amp;gt; πρόβλημα με φυσική μνήμη &lt;/li&gt;    &lt;li&gt;Αλγόριθμοι με τοπικότητα αναφορών (εδώ δόθηκε ένα ακόμα οπτικό παράδειγμα με δύο αλγορίθμους για πράξη πινάκων) &lt;/li&gt;    &lt;li&gt;Γνωρίστε τα δεδομένα σας, το κόστος τους, το βάρος τους, το “σχήμα τους” &lt;/li&gt;    &lt;li&gt;Memory management, εντοπισμός bottlenecks &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;u&gt;&lt;strong&gt;Modeling in the Enterprise with Microsoft &amp;quot;Oslo&amp;quot; – Νατάσα Μανουσοπούλου&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/22102009108_42FB9CF8.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="22102009108" border="0" alt="22102009108" src="http://www.studentguru.gr/blogs/grnemo/22102009108_thumb_270A6800.jpg" width="244" height="184" /&gt;&lt;/a&gt; &lt;a href="http://www.studentguru.gr/blogs/grnemo/22102009109_464D0ED3.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="22102009109" border="0" alt="22102009109" src="http://www.studentguru.gr/blogs/grnemo/22102009109_thumb_032190A6.jpg" width="244" height="184" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Μία πραγματικά φοβερή τεχνική παρουσίαση από την Νατάσα, για το &lt;a href="http://www.microsoft.com/soa/products/oslo.aspx" target="_blank"&gt;OSLO&lt;/a&gt;, την πλατφόρμα μοντελισμού της Microsoft που βρίσκεται σε εμβρυακό στάδιο ακόμα, επιτρέποντας σε ανθρώπους που προέρχονται από διαφορετικά περιβάλλοντα να επικοινωνούν μεταξύ τους, κατά τη διαδικασία του requirements engineering. Η έμφαση δίνεται κυρίως στους προγραμματιστές, εφοδιάζοντάς τους, με το επίπεδο γενίκευσης εκείνο, που θα τους βοηθήσει στην μετέπειτα διαδικασία. Η πλατφόρμα αποτελείται από τρία πράγματα: το εργαλείο, την “γλώσσα” για να μπορείς να ορίζεις ειδικές γλώσσες για το πρόβλημά σου και ένα κοινό σημείο αποθήκης μοντέλων, ώστε μετά να πέσουν όλοι πάνω για την παρουσίαση των εννοιών που μοντελοποιήθηκαν (είτε μέσω ενός Entity Framework Diagram, είτε μέσω ui και της πανίσχυρης XAML, είτε ακόμα μέσα από Sharepoint). Τρία πράγματα για αρχή, λοιπόν: Διαμοιρασμός πληροφορίας, ευκολία παραμετροποίησης, διαχείριση αλλαγών (στα requirements). Το πρώτο που πρέπει να καταλάβουμε είναι πως αποκτούμε μία &lt;strong&gt;formal γλώσσα για να περιγράψουμε την φυσική γλώσσα&lt;/strong&gt; και &lt;strong&gt;μετα-δεδομένα για να περιγράψουμε κώδικα&lt;/strong&gt;. Τι καλύτερο δηλαδή από το να έχουμε τον προγραμματιστή μας δίπλα, στην συνέντευξη για requirements document, και την ώρα που μαθαίνουμε το domain του πελάτη να γράφουμε δίπλα κάτι τόσο generic που μετά θα το κάνουμε, ui ή business object ή report ή ή ή… Η Νατάσα μας έδειξε ένα πολύ όμορφο παράδειγμα με μοντελοποίηση ερωτηματολογίου το οποίο το δόμησε με MGrammar και το παρουσίασε με Sharepoint. Παραθέτω ένα παράδειγμα μοντελοποίησης του πεδίου “Οικογένεια” που βρήκα &lt;a href="http://msdn.microsoft.com/en-us/oslo/default.aspx" target="_blank"&gt;εδώ&lt;/a&gt;. Interesting huh? :) &lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;  module Example {    
&amp;#160;&amp;#160;&amp;#160; language Family {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; interleave Whitespace = &amp;#39; &amp;#39;|&amp;#39;\n&amp;#39;|&amp;#39;\r&amp;#39;|&amp;#39;\t&amp;#39;;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; token Name = (&amp;#39;a&amp;#39;..&amp;#39;z&amp;#39;|&amp;#39;A&amp;#39;..&amp;#39;Z&amp;#39;)+;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; syntax Persons     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = p:Person     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; =&amp;gt; [p]     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | list:Persons &amp;quot;&amp;quot;,&amp;quot;&amp;quot; p:Person     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; =&amp;gt; [valuesof(list), p];   &amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; syntax Children    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = &amp;quot;&amp;quot;{&amp;quot;&amp;quot; p:Persons &amp;quot;&amp;quot;}&amp;quot;&amp;quot; &amp;quot;&amp;quot;;&amp;quot;&amp;quot;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; =&amp;gt; p;     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; syntax Person     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = first:Name last:Name     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; =&amp;gt; Person {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; First { first },     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Last { last }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | first:Name last:Name c:Children     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; =&amp;gt; Person {     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; First { first },     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Last { last },     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Children { c }     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; };     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; syntax Main     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; = p:Person*     
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; =&amp;gt; p;     
&amp;#160;&amp;#160;&amp;#160; }     
}  &lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;Και έτσι μπορώ να γράψω στον κώδικα, το δεδομένο μου το οποίο μπαίνει σε ένα πολύ όμορφο POCO. Πανέμορφο!&lt;/p&gt;  &lt;p&gt;&lt;textarea name="code" class="c#"&gt;  Bob Williams   
{     
&amp;#160;&amp;#160;&amp;#160; Joanie Williams,    
&amp;#160;&amp;#160;&amp;#160; Cathy Williams,    
&amp;#160;&amp;#160;&amp;#160; Bob Williams    
&amp;#160;&amp;#160;&amp;#160; {    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Josh Williams,    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Jennie Williams,    
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Julie Williams    
&amp;#160;&amp;#160;&amp;#160; };    
};  &lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Reliability, Availability, and Scalability - Have your cake and eat it too - Udi Dahan&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/22102009110_427F4436.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" title="22102009110" border="0" alt="22102009110" src="http://www.studentguru.gr/blogs/grnemo/22102009110_thumb_58F1E2BD.jpg" width="244" height="184" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Πραγματική έμπνευση η παρουσίαση του διάσημου Udi Dahan… Μας παρουσίασε τις έννοιες reliability, availability και scalability στο enterprise service bus. Τι γίνεται όταν έχουμε έναν Application Server και έναν DB Server και κάποιος συνδυασμός τους ή ένας από τους δύο βρεθεί εκτός λειτουργίας προσωρινα; Πώς χτίζουμε υποδομή για να αποφύγουμε προβλήματα όπως μη διαθεσιμότητα, τα οποία θα επηρρεάσουν το business μας; Όμορφες ιδέες και απλές στην υλοποίηση, ξεκαθαρίζουν το τοπίο, όπως one way messaging ( request response / publish subscribe), handling messages, rolling back business operations που αποτελούνται από διάφορες πηγές (π.χ., ανεξάρτητα orchestrated Web Services) με τέτοιο τρόπο που θα είναι σαν πραγματικό πισωγύρισμα στο χρόνο. Ιδέες όπως οι παραπάνω γίνονται encapsulate στο open source project του Udi ονόματι &lt;a href="http://www.nservicebus.com/" target="_blank"&gt;NServicebus&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Πολύ δυνατές παρουσίες με πλούσιες ιδέες, πρακτικές, τάσεις και τεχνολογίες, που χτίζουν καλύτερα οικοδομήματα. &lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=1st Architecture Days post-event comments&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/10/23/1st-architecture-days-post-event-comments.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="1st Architecture Days post-event comments";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/10/23/1st-architecture-days-post-event-comments.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=107172" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="events" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/events/default.aspx" /><category term="architecture" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/architecture/default.aspx" /></entry><entry><title>Ασφαλής χρήση FileSystemWatcher</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/10/12/filesystemwatcher.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/10/12/filesystemwatcher.aspx</id><published>2009-10-11T22:24:27Z</published><updated>2009-10-11T22:24:27Z</updated><content type="html">&lt;p&gt;Υπάρχουν σενάρια που χρειάζεται να ξέρετε πότε ένα καινούριο αρχείο δημιουργείται σε έναν κατάλογο, ή πότε γίνεται rename, ή πότε αλλάζει το Last Changed timestamp για να κάνετε διάφορες εργασίες. Έστω το σενάριο, ότι έχετε ένα εξωτερικό εργαλείο που κάνει κάποια λειτουργία μετατροπής αρχείων. Για να μπορείτε να αντιληφθείτε πότε το αρχείο γράφτηκε στο folder που παρατηρείτε και να αντιγράψετε το αρχείο αυτό κάπου αλλού, ή να το επεξεργαστείτε, μπορείτε να χρησιμοποιήσετε το FileSystemWatcher του .NET. Παρόλα αυτά υπάρχει ένα θέμα εδώ. Ο &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx" target="_blank"&gt;FileSystemWatcher&lt;/a&gt; είναι καθαρά για reporting σκοπούς. Αν εσείς χρειάζεστε το αρχείο αυτούσιο, θα πρέπει να γνωρίζετε για το πότε το αρχείο είναι επιπλέον ελεύθερο από οποιοδήποτε άλλο process (π.χ., εκείνου που το αντιγράφει στο folder που κοιτάται). Ένα απλός και γρήγορος τρόπος, για να αποφύγουμε το IOException σε τέτοια περίπτωση είναι ο παρακάτω:&lt;/p&gt;  &lt;p&gt;Δημιουργούμε μία συνάρτηση που ελέγχει για το αν το αρχείο είναι κλειδωμένο.&lt;/p&gt;  &lt;p&gt;   &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6d298b62-13a9-4359-b449-a87af1c5c0fa" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow:auto;font-family:Microsoft Sans Serif;font-size:15,75;"&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; CheckFileLock(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt; filename)
{
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;try&lt;/span&gt;&lt;span style="color:#000000;"&gt;
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; (FileStream inputStream &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; File.Open(filename, 
                                    FileMode.Open,
                                    FileAccess.Read,
                                    FileShare.None))
        {
            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
        }
    }
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;catch&lt;/span&gt;&lt;span style="color:#000000;"&gt; (IOException)
    {
      &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;Log maybe&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;false&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
    }
}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Στη συνέχεια ο Watcher σας για να δουλέψει θα χρειαστεί τον event handler για το event Created. Ο Handler αυτός θα πρέπει να τσεκάρει ανά τακτά χρονικά διαστήματα (απλή λύση) για τη διαθεσιμότητα του αρχείου και that’s it.&lt;/p&gt;

&lt;p&gt;
  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f92db8f3-38a5-4f06-8f1b-2d271036ff32" class="wlWriterEditableSmartContent"&gt;&lt;pre style="background-color:#FFFFFF;overflow:auto;font-family:Microsoft Sans Serif;font-size:15,75;"&gt;&lt;span style="color:#0000FF;"&gt;private&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt;&lt;span style="color:#000000;"&gt; onFileCreated(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; sender, FileSystemEventArgs e)
{
    DateTime receivedTime &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; DateTime.Now;
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#000000;"&gt; delay &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; ...
    &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;while&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;)
    {
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (CheckFileLock(e.FullPath))
        {
            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;Do whatever you want safely&lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;break&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
        }
        TimeSpan elapsedTime &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; DateTime.Now &lt;/span&gt;&lt;span style="color:#000000;"&gt;-&lt;/span&gt;&lt;span style="color:#000000;"&gt; receivedTime;
        &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (elapsedTime.TotalMinutes &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; max)
        {
            &lt;/span&gt;&lt;span style="color:#008000;"&gt;//&lt;/span&gt;&lt;span style="color:#008000;"&gt;Logging definitely &lt;/span&gt;&lt;span style="color:#008000;"&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;            &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;break&lt;/span&gt;&lt;span style="color:#000000;"&gt;;
        }
        Thread.Sleep(delay);
    }
}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Στην καθυστέρηση που εισάγετε μπορεί κάποιος να χρησιμοποιήσει όποια στρατηγική θέλει, από σταθερό αριθμό ή κάποιο είδους αυξανόμενου.&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Ασφαλής χρήση FileSystemWatcher&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/10/12/filesystemwatcher.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Ασφαλής χρήση FileSystemWatcher";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/10/12/filesystemwatcher.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=106909" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="C#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/C_2300_/default.aspx" /><category term=".NET" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/.NET/default.aspx" /></entry><entry><title>Tip of the day #2: Problem with your WCF hosting? Probably an ABC matter!</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-2-problem-with-your-wcf-hosting-probably-an-abc-matter.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-2-problem-with-your-wcf-hosting-probably-an-abc-matter.aspx</id><published>2009-09-30T18:19:46Z</published><updated>2009-09-30T18:19:46Z</updated><content type="html">&lt;p&gt;Today I faced a nice little issue. It wasn’t something mindblasting and the solution wasn’t somehow innovative, but rather a 5-minute issue to resolve (If I had said the ABC out loud first). Instead it was a 30 minutes work. I was asked to make a new WCF web service to provide some functionality for our business case. Some structural background on the project I was working on: It is a Silverlight application, with client-side data management UI, a server-side with (web) services supporting our business logic and a LOT of (disconnected) business objects flying around like crazy, between the web application and the client. This orchestration was ment to be disturbed until today, by me, creating two more WSs’, the first for a certain operation taking place server-side and a second, stand alone, little web service doing some stuff at a third tier in another machine (which is used by the former). I spent more than 30 minutes in the morning (before coffee) asking myself what have I done wrong, and the client (first WS) didn’t recognize my configuration elements. The same dialog between the debbuger again and again, under various tweakings… &lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;-Visual Studio says: Sorry, I cannot find default endpoint element that references contract IService******* in the ServiceModel client configuration section.&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;-Aggelos says: I am going by the book, what is wrong?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;-Visual Studio says: Hahahaha, lolz, think again, you happy programer!&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;What was going wrong? Go back to the beginning, and remember. All the server functionality is supported by a certain web application with it’s own web config. My web service (the client one) had it’s own project under a WCF service library project. The WCF was hosted by the Web Application so… yeah that’s the answer. The configuration resides in web.config of course, even if the WCF (library) is somewhere else…&lt;/p&gt;  &lt;p&gt;ABC stands for Address, Binding, Contract…missing one of them, breaks all of them… what about missing all of them? :P:P:P:P:P&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Tip of the day #2: Problem with your WCF hosting? Probably an ABC matter!&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-2-problem-with-your-wcf-hosting-probably-an-abc-matter.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Tip of the day #2: Problem with your WCF hosting? Probably an ABC matter!";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-2-problem-with-your-wcf-hosting-probably-an-abc-matter.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=106380" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="tip" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/tip/default.aspx" /><category term="WCF" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/WCF/default.aspx" /></entry><entry><title>Tip of the day #1: Love and take care of your MSDTC connectivity</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-1-love-and-take-care-of-your-msdtc-connectivity.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-1-love-and-take-care-of-your-msdtc-connectivity.aspx</id><published>2009-09-30T18:14:06Z</published><updated>2009-09-30T18:14:06Z</updated><content type="html">&lt;p&gt;You have a nice day, but something is missing. Your first debug tryout, after some hours of refactoring and new feature coding. After the successful built, you get your first exception (the usual handled exception that is logging something). Usually the exception is self-explained, it gives you the right information and with a little bit of help from the call stack you pin-point the failure. So, let’s see the code…xmmmm…the error is somewhere on my tested-and-working-perfect-until-now part of my module… The exception is accompanied with a &lt;u&gt;transaction lock&lt;/u&gt;. But why? You keep unlocking the database via the Activity Monitor of SQL Management Studio, you retest the code, step by step, but you can’t pinpoint the the problem. Why my thread does that to me, what have I done? Why does it lock my data during the business object save?&lt;/p&gt;  &lt;p&gt;As a matter of fact, during the day, I have done 3 things in general:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I have been coding in a region, not even executed when the lockout occurs. &lt;/li&gt;    &lt;li&gt;I have participated in updating the db server (another physical machine)&lt;/li&gt;    &lt;li&gt;I have deployed several updates to my system, including SP3, during the previous night. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So after an hour of pair-debugging, my colleague concludes that there isn’t anything wrong with the code itself, so the first bullet is gone. The problem occurs when data switches transaction mode during persistence, to distributed transaction, so we have two machines, with “maybe” recently-damaged &lt;a href="http://msdn.microsoft.com/en-us/library/ms190799.aspx"&gt;MSDTC&lt;/a&gt; settings. Either my machine or the db server. By restarting after checking the settings at the db server, the problem still exists. So, the 2nd bullet is gone too. What is wrong with my pc after all? &lt;/p&gt;  &lt;p&gt;And then, after a couple of hours I hear a &lt;a href="http://www.dotnetzone.gr/cs/blogs/palladin/default.aspx"&gt;magic voice&lt;/a&gt; screaming to me: OMG!!! Check Immediately your firewall! And there it was, the filthy, stupid (not even a) bug… that had jumped from the code and settled somewhere else. The newly-during-the-night-updated system, had restored settings and rules at firewall, ending the communication of my Microsoft Distributed Transaction Coordinator with the outer world…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Tragic….but still funny :P&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Tip of the day #1: Love and take care of your MSDTC connectivity&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-1-love-and-take-care-of-your-msdtc-connectivity.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Tip of the day #1: Love and take care of your MSDTC connectivity";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-1-love-and-take-care-of-your-msdtc-connectivity.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=106378" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="tip" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/tip/default.aspx" /><category term="msdtc" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/msdtc/default.aspx" /><category term="sql server" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/sql+server/default.aspx" /></entry><entry><title>Tip of the day #0: Admit your SLCM’s</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-0-admit-your-slcm-s.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-0-admit-your-slcm-s.aspx</id><published>2009-09-30T18:07:40Z</published><updated>2009-09-30T18:07:40Z</updated><content type="html">&lt;p&gt;How many of you, have experienced an embarrassing –at yourself- code bug situation? You know, that you were better than this one, but you don’t want to admit it. You go home at night, thinking about it. You dream of it, laughing in your face…it’s laugh jumps out, through the code blocks, haunting your existence… it isn’t a logical error in communication of the wireless sensor network you recently engineered, it is a bug, residing in your configuration file… it isn’t an algorithmic fault, in your genetic algorithm … your algorithm doesn’t execute well because of the non-printable character in this f%@#$@#$ string (or char* I still love you). Finally, your business object doesn’t lazy load… -why god…pls give me strength –[god]My child take some rest, you have a buggy old version of your ORMapper, go get some sleep.&lt;/p&gt;  &lt;p&gt;Admit your stupid little code mistakes. They are part of your professionalism. I will post some worth-mentioning situations just for fun (and non profit at all - :P:P:P).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/computerbug1_18C0D6A1.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="computer-bug[1]" border="0" alt="computer-bug[1]" src="http://www.studentguru.gr/blogs/grnemo/computerbug1_thumb_5A979622.jpg" width="244" height="163" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Tip of the day #0: Admit your SLCM’s&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-0-admit-your-slcm-s.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Tip of the day #0: Admit your SLCM’s";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/09/30/tip-of-the-day-0-admit-your-slcm-s.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=106377" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="tip" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/tip/default.aspx" /></entry><entry><title>Windows Sensor and Location platform</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/08/25/windows-sensor-and-location-platform.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/08/25/windows-sensor-and-location-platform.aspx</id><published>2009-08-24T21:58:15Z</published><updated>2009-08-24T21:58:15Z</updated><content type="html">&lt;p&gt;Τα Windows 7 περιέχουν ενσωματωμένη (native) υποστήριξη για διαχείριση αισθητήρων μαζί με μία προγραμματιστική πλατφόρμα που την συνοδεύει. Αφορά location sensors, temperature, accelerometer, ambient light, moisture, camera, RFID και πολλούς ακόμα τύπους αισθητήρων, που κοινώς φέρνουν τον enterprise developer πιο κοντά στις εφαρμογές διάχυτου υπολογισμού, από το να κάνουν μία απλή εφαρμογή mashup που θα χρησιμοποιεί δεδομένα από gps μέχρι μία sophisticated πλατφόρμα &lt;a href="http://www.studentguru.gr/blogs/grnemo/archive/2009/01/21/multisensor-data-fusion-theory-and-practice.aspx"&gt;data fusion&lt;/a&gt;. H πλατφόρμα ονομάζεται Sensor and Location Platform και περιλαμβάνει τόσο managed API (C#) όσο και native (C++ με δικό μας memory management). Στην ουσία αποτελείται από 4 πράγματα όλη η πλατφόρμα:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;To DDI (device driver interface) παρέχει μέσω των Windows έναν πρότυπο τρόπο για να συνδέονται οι αισθητήρες στο σύστημα και να μπορούν να παρέχουν σε αυτό πληροφορίες &lt;/li&gt;    &lt;li&gt;Το Windows Sensor API για την διαχείριση των δεδομένων &lt;/li&gt;    &lt;li&gt;To Windows Location API (χρησιμοποιεί το 2&lt;sup&gt;ο&lt;/sup&gt; layer) για την διαχείριση χωρικών δεδομένων &lt;/li&gt;    &lt;li&gt;Το Location and Other Sensors Control Panel για διαχειριστικά θέματα μέσα, συσχετίζοντας χρήστες με υποδομές αισθητήρων. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Και το software stack φαίνεται παρακάτω:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/clip_image0014_2557521F.jpg"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="clip_image001[4]" border="0" alt="clip_image001[4]" src="http://www.studentguru.gr/blogs/grnemo/clip_image0014_thumb_20086B6E.jpg" width="320" height="241" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Μία πρώτη γεύση μπορείτε να δείτε στο &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=1c333f06-fadb-4d93-9c80-402621c600e7&amp;amp;displaylang=en"&gt;Windows 7 training kit&lt;/a&gt; που έχει μία απλή WPF εφαρμογή, που αλλάζει τη φωτεινότητα της προβαλλόμενης εικόνας με δεδομένα από sensors έντασης φωτός, με τη μισή μαγεία στο XAML (old news) και την άλλη μισή στο &lt;b&gt;SensorHelper.cs&lt;/b&gt; αρχείο (Windows 7 platform). Στο View Model του sensor δε (στο SensorViewModel.cs) θα γλείφετε τα δάχτυλά σας, με κάτι δηλώσεις του τύπου που βλέπετε παρακάτω (constructor). Με την πρώτη ματιά βλέπετε ότι τα πράγματα έχουν προσαρμοστεί ακριβώς στο πεδίο των εφαρμογών επίγνωσης πλαισίου με όλο τον boilerplate κώδικα να έχει εισαχθεί μέσα στη πλατφόρμα με ενσωματωμένους τύπους δεδομένων, methods για data retrieval κτλ κτλ.&lt;/p&gt;  &lt;p&gt;public SensorViewModel()    &lt;br /&gt;{     &lt;br /&gt;&amp;#160; _sensor = new SensorHelper&amp;lt;AmbientLightSensor, AmbientLightSensor.LuminousIntensity&amp;gt;();     &lt;br /&gt;&amp;#160; _sensor.Initialize();     &lt;br /&gt;&amp;#160; _acceleromaterSensor = new SensorHelper&amp;lt;Accelerometer3D, Accelerometer3D.Acceleration3D&amp;gt;();     &lt;br /&gt;&amp;#160; _acceleromaterSensor.Initialize();     &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;Διαβάστε το αντίστοιχο συνοπτικό docx του lab να δείτε τι εννοώ!!! Επίσης μπορείτε να ανατρέξετε για πληροφορίες της πλατφόρμας στα παρακάτω:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Videos από channel 9:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://channel9.msdn.com/tags/Sensor+and+Location+Platform/"&gt;http://channel9.msdn.com/tags/Sensor+and+Location+Platform/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Πηγές:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.microsoft.com/whdc/device/sensors/default.mspx"&gt;http://www.microsoft.com/whdc/device/sensors/default.mspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd318953%28VS.85%29.aspx"&gt;Sensor Programming Guide (MSDN Library)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd464636%28VS.85%29.aspx"&gt;Location Programming Guide (MSDN Library)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://code.msdn.microsoft.com/SensorsAndLocation"&gt;Sensor and Location Platform Developer Resources&lt;/a&gt;&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Windows Sensor and Location platform&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/08/25/windows-sensor-and-location-platform.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Windows Sensor and Location platform";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/08/25/windows-sensor-and-location-platform.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=103271" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="C#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/C_2300_/default.aspx" /><category term="Pervasive Computing" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/Pervasive+Computing/default.aspx" /><category term="data fusion" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/data+fusion/default.aspx" /></entry><entry><title>NScanner: Port Scanner / Port Sweeper</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/06/02/nscan-port-scanner-port-sweeper.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/06/02/nscan-port-scanner-port-sweeper.aspx</id><published>2009-06-02T18:23:00Z</published><updated>2009-06-02T18:23:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;Πρόσφατα ολοκληρώσαμε έναν ανιχνευτή κατάστασης θυρών, ο οποίος να παρουσιάζει διπλή λειτουργικότητα, να είναι και Port scanner αλλά και Port sweeper. Ο Port Scanner θα δέχεται ως είσοδο μια δ/νση ΙΡ (ή hostname) και range από πόρτες (TCP/UDP) που θα θέλαμε να ανιχνεύσουμε. Ο Port Sweeper θα δέχεται ως είσοδο μια πόρτα (TCP/UDP) που θα θέλαμε να ανιχνεύσουμε και λίστα από δ/νσεις ΙΡ (ή DNS name). Η εφαρμογή υλοποιεί TCP, UDP και SYN scan με επιλογές που να τα παραμετροποιούν. &lt;/p&gt;
&lt;p align="justify"&gt;Η εφαρμογή αποτελείται από το βασικό παράθυρο στο οποίο μπορεί ο χρήστης να κάνει τις κατάλληλες παραμετροποιήσεις και να εισάγει τα στοιχεία που αυτός θέλει. Τα αποτελέσματα εκτυπώνονται στα δεξιά του παραθύρου ενώ στο κάτω μέρος υπάρχει και ένα progress bar το οποίο ενημερώνει τον χρήστη για το ποσοστό του ελέγχου που έχει απομείνει. Λοιπές λειτουργίες όπως logging, εκτύπωση ονομάτων θυρών που αναφέρονται κτλ, περιγράφονται παρακάτω.&lt;/p&gt;
&lt;h3&gt;TCP Scan&lt;/h3&gt;
&lt;p align="justify"&gt;Στο TCP Scan αξιοποιείται η αναλυτική διαδικασία σύνδεσης με Berkeley sockets σε .NET (Socket Class (System.Net.Sockets)). O σκοπός που γίνεται αυτό είναι γιατί έτσι μπορούμε να έχουμε πλήρη έλεγχο κατά την δημιουργία των sockets. H γενική ιδέα είναι ότι, πραγματοποιείται ολόκληρη η διαδικασία του 3-way handshake, κατά την εγκαθίδρυση της σύνδεσης, το οποίο αποτυγχάνει κάτω από συγκεκριμένες συνθήκες, που αποκαλύπτουν την κατάσταση της θύρας. Στον παρόν port scanner που περιγράφεται, ανιχνεύονται θύρες σε τρεις διακριτές καταστάσεις σύμφωνα με την απόκριση τους: ανοικτές, κλειστές φιλτραρισμένες. Οι ανοικτές θύρες (πραγματοποιούν σύνδεση) αποκαλύπτουν ότι η port δεν υπόκειται σε έλεγχο firewall σχετικά με την κατάστασή της και επιτρέπει τις συνδέσεις (ανοικτή και ταυτόχρονα κάποια υπηρεσία την χρησιμοποιεί για να εξυπηρετεί προγράμματα «πελάτες»). Η δεύτερη κατηγορία (κλειστές) αναφέρεται στην κατάσταση όπου μία θύρα αποκρίνεται ότι δεν δέχεται συνδέσεις. Τέλος η κατηγορία στην οποία υπόκεινται οι φιλτραρισμένες θύρες, είναι όταν δεν δεχόμαστε απόκριση στην αποστολή αίτησης προς εκείνες.&lt;/p&gt;
&lt;h3&gt;UDP Scan&lt;/h3&gt;
&lt;p align="justify"&gt;Στο UDP Scan χρησιμοποιείται μία παρόμοια μέθοδος (προγραμματιστικά), ορίζοντας μία περίοδο timeout που επηρεάζει το αποτέλεσμα. Το πρωτόκολλο UDP δεν έχει ανάγκη για SYN, FIN ή κάποια άλλη διαδικασία εγκαθίδρυσης σύνδεσης. Με το πρωτόκολλο UDP τα πακέτα αποστέλλονται και λαμβάνονται χωρίς κάποια προειδοποίηση, πράγμα που απλοποιεί την διαδικασία του port scanning (με περισσότερο αβέβαια αποτελέσματα βέβαια). Οι καταστάσεις που εντοπίζουμε είναι τρεις: Closed, Open/Filtered, Open. &lt;/p&gt;
&lt;h3&gt;SYN Scan&lt;/h3&gt;
&lt;p align="justify"&gt;Στην μέθοδο SYN Scan συλλέγεται πληροφορία για την εμπλεκόμενη θύρα πριν ολοκληρωθεί η διαδικασία της εγκαθίδρυσης σύνδεσης. Όταν μία θύρα αναγνωρίζεται ως ανοικτή το TCP Handshake τερματίζεται με σήμα RST, πριν ακόμα ολοκληρωθεί η διαδικασία. Αυτή η τεχνική συνήθως αναφέρεται και ως half open scan. Σε περίπτωση που η εφαρμογή λάβει σήμα RST μετά από σήμα SYN, σημαίνει ότι η θύρα είναι κλειστή.&lt;/p&gt;
&lt;p align="justify"&gt;Για την παρούσα μέθοδο χρειάστηκε η κατασκευή των πακέτων με αναλυτικό τρόπο όπως επίσης και οι αποκρίσεις με σήματα RST σε περίπτωση που το άλλο άκρο αποκριθεί θετικά (SYN &amp;amp; ACK). Η αναγνώριση των στόχων, των gateway και πολλών στοιχείων που χρειάζονται για την κατασκευή των πακέτων, έχουν γίνει προγραμματιστικά στην συνάρτηση Connect που υπάρχει στην κλάση SynConnectCall.&lt;/p&gt;
&lt;p align="justify"&gt;Τα πλεονεκτήματα της συγκεκριμένης μεθόδου είναι ότι το γεγονός ποτέ δεν καταγράφεται από την εφαρμογή του στόχου, γιατί απλά δεν πραγματοποιείται σύνδεση TCP. Αυτό είναι ένα κατά πολύ πιο «αθόρυβο» scan από άλλα, τα οποία παρουσιάζουν μικρότερη ορατότητα από πλευράς του στόχου. Παρέχει πληροφορίες όπως open, closed και filtered θύρες.&lt;/p&gt;
&lt;h3&gt;Ανάπτυξη σε C#&lt;/h3&gt;
&lt;p align="justify"&gt;Η εφαρμογή μας υλοποιήθηκε σε περιβάλλον .NET 3.5 και σε γλώσσα προγραμματισμού C Sharp (C#), ενώ για το γραφικό περιβάλλον της εφαρμογής χρησιμοποιήσαμε Winforms. Για την υλοποίηση της λειτουργικότητας SYN Scan χρησιμοποιήθηκε η βιβλιοθήκη libpcap&lt;a href="http://www.tcpdump.org/"&gt;[1]&lt;/a&gt;. Επίσης για της ανάγκες υλοποίησης σε C# χρησιμοποιήθηκε η υπό ανάπτυξη βιβλιοθήκη που ενθυλακώνει τις native κλήσης συστήματος της βιβλιοθήκης της libpcap ώστε να είναι δυνατή η χρησιμοποίησή της μέσα από περιβάλλον .NET. H εν λόγω βιβλιοθήκη ονομάζεται SharpPcap και διανείμετε δωρεάν, μέσα από το SourceForge.ΝΕΤ&lt;a href="https://sourceforge.net/projects/sharppcap/"&gt;[2]&lt;/a&gt;. Αξίζει να σημειωθεί ότι έγιναν αλλαγές στον κώδικα του wrapper, όπως και διορθώθηκαν λάθη τα οποία αναφέρθηκαν στην ομάδα ανάπτυξης του, για να ληφθούν υπόψη στη περαιτέρω διαδικασία ανάπτυξής του &lt;a href="https://sourceforge.net/forum/forum.php?thread_id=3289290&amp;amp;forum_id=711443"&gt;[3]&lt;/a&gt; &lt;a href="https://sourceforge.net/forum/forum.php?thread_id=3285070&amp;amp;forum_id=711443"&gt;[4]&lt;/a&gt;.&lt;/p&gt;
&lt;p align="justify"&gt;Οι μέθοδοι που υλοποιούνται ενθυλακώνονται στις αντίστοιχες κλάσεις &amp;lt;Protocol&amp;gt;ConnectCall (π.χ., το tcp scan υλοποιείται στην TcpConnectCall).&lt;/p&gt;
&lt;h3&gt;Screenshots&lt;/h3&gt;
&lt;table cellspacing="0" cellpadding="2"&gt;

&lt;tr&gt;
&lt;td&gt;
&lt;p align="center"&gt;Port Sweeping&lt;a href="http://www.studentguru.gr/blogs/grnemo/image_4A853FB9.png"&gt; &lt;br /&gt;&lt;img style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="image" border="0" alt="image" src="http://www.studentguru.gr/blogs/grnemo/image_thumb_68EF80A2.png" width="244" height="228" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;/td&gt;
&lt;td&gt;
&lt;p align="center"&gt;UDP Port Scanning &lt;br /&gt;&lt;a href="http://www.studentguru.gr/blogs/grnemo/image_2F003DB6.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="image" border="0" alt="image" src="http://www.studentguru.gr/blogs/grnemo/image_thumb_1453A19D.png" width="244" height="228" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;em&gt;H εφαρμογή αναπτύχθηκε στα πλαίσια εργασίας για το μάθημα “Ασφάλεια υπολογιστών και Δικτύων”, Οικονομικό Πανεπιστήμιο Αθηνών, ΠΜΣ Πληροφοριακά Συστήματα 2008-2009, από τους Άγγελος Μπιμπούδη (εμένα) και Αναστάσιο Νεραντζίνη και καταχωρήθηκε στο codeplex από όπου θα εξελιχθεί/βελτιωθεί. Η άδεια χρήσης είναι GNU Library General Public License (LGPL).&lt;/em&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://nscanner.codeplex.com/"&gt;http://nscanner.codeplex.com/&lt;/a&gt;&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=NScanner: Port Scanner / Port Sweeper&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/06/02/nscan-port-scanner-port-sweeper.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="NScanner: Port Scanner / Port Sweeper";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/06/02/nscan-port-scanner-port-sweeper.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=69686" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="C#" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/C_2300_/default.aspx" /><category term="winforms" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/winforms/default.aspx" /><category term="port scanner" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/port+scanner/default.aspx" /><category term="codeplex" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/codeplex/default.aspx" /></entry><entry><title>Enterprise Architect CASE Tool για Ανάπτυξη Λογισμικού</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/03/15/enterprise-architect-case-tool.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/03/15/enterprise-architect-case-tool.aspx</id><published>2009-03-15T00:15:55Z</published><updated>2009-03-15T00:15:55Z</updated><content type="html">&lt;p align="justify"&gt;Μετά από μία συζήτηση που είχα σήμερα στο &lt;a href="http://www.studentguru.gr/blogs/grnemo/archive/2009/03/14/mediacamp2-day-1.aspx" target="_blank"&gt;MediaCamp2&lt;/a&gt; με τον συνάδελφο &lt;a href="http://kcorax.spaces.live.com/" target="_blank"&gt;Γιώργο Κασσελάκη&lt;/a&gt; σχετικά με το &lt;a href="http://www.sparxsystems.com/products/ea/" target="_blank"&gt;Enterprise Architect&lt;/a&gt; της &lt;a href="http://www.sparxsystems.com/" target="_blank"&gt;Sparx Systems&lt;/a&gt;, ήθελα να μοιραστώ μαζί σας την χρήση αυτού του εργαλείου. &lt;/p&gt;  &lt;p align="justify"&gt;&lt;img style="display:inline;margin-left:0px;margin-right:0px;" src="http://www.sparxsystems.com/images/products/logos/EA.png" align="left" alt="" /&gt; Το ανακάλυψα φέτος για μία εργασία Τεχνολογίας Λογισμικού στο αντίστοιχο πρόγραμμα του μεταπτυχιακού μου και μπορώ να πώ ότι ήταν πολύ καλή λύση για όσα θέλαμε να κάνουμε, ανακαλύπτωντας σε κάθε βήμα πόσες περισσότερες δυνατότητες έχει από όσες το θέλαμε για τις ανάγκες της εργασίας μας. To Enterprise Architect είναι μία ολοκληρωμένη σουιτα από &lt;a href="http://en.wikipedia.org/wiki/Computer-aided_software_engineering" target="_blank"&gt;CASE functionality&lt;/a&gt;. Case tools είναι κατά βάση τα εργαλεία που βοηθούν την διαδικασία ανάπτυξης λογισμικού καθόλες τις φάσεις ανάπτυξης, από Requirements Engineering μέχρι τελικό deployment modeling, εξοπλισμένο με πλήρες &lt;a href="http://en.wikipedia.org/wiki/Requirements_Traceability" target="_blank"&gt;tracing&lt;/a&gt; από τα requirements μέχρι την υλοποίηση.&lt;/p&gt;  &lt;p align="justify"&gt;Είναι χτισμένο πάνω στο 2.1 specification της UML αλλά δεν περιορίζεται μέχρι εκεί. Περιέχει extensions για modeling domain όπως για παράδειγμα, modeling επιχειρησιακών διαδικασιών μέσω workflows κτλ. &lt;/p&gt;  &lt;p align="justify"&gt;Υποστηρίζει τα παρακάτω διαγράμματα:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Structural Diagrams&lt;/strong&gt;:    &lt;br /&gt;• Class    &lt;br /&gt;• Object    &lt;br /&gt;• Composite    &lt;br /&gt;• Package     &lt;br /&gt;• Component    &lt;br /&gt;• Deployment     &lt;br /&gt;&lt;strong&gt;Behavioral Diagrams:&lt;/strong&gt;    &lt;br /&gt;• Use Case    &lt;br /&gt;• Communication    &lt;br /&gt;• Sequence    &lt;br /&gt;• Interaction Overview    &lt;br /&gt;• Activity    &lt;br /&gt;• State    &lt;br /&gt;• Timing     &lt;br /&gt;&lt;strong&gt;Extended:&lt;/strong&gt;    &lt;br /&gt;• Analysis (simple activity)    &lt;br /&gt;• Custom (for requirements, change, UI) &lt;/p&gt;  &lt;p align="justify"&gt;Επίσης έχει ένα αρκετά εύχρηστο κομμάτι για Versioning που πιστεύουμε ότι καλύπτει και τις πιο απαιτητικές ανάγκες. Στην εργασία μας, εμείς, είχαμε στήσει SVN version control (υποστηρίζει και SCC) όπου ενώ ο κάθε ένας μας είχε το βασικό αρχείο του project, υπήρχε εκ των έσω επικοινωνία με το server κομμάτι, πραγματοποιώντας τα commit και τα update under the hood. Το κομμάτι του versioning ήταν πολύ σημαντικό για εμάς και μας διευκόλυνε άπειρα. Το EA παράγει και αντιστρέφει (reverse engineer) κώδικα από τις γλώσσες: C++, C#, Java, Delphi, VB.Net, Visual Basic, ActionScript, PHP and Python. Η δική μας προσέγγιση ήταν με ASP.NET και C# και από την έρευνα που κάναμε, το αποτέλεσμα που είδαμε στο generation ήταν ότι ήταν το καλύτερο από πλευράς παραγωγής κώδικα (πράγμα που επιβεβαίωσαν και άλλοι, πιο έμπειροι από εμάς, στον χώρο). Βέβαια για να μπορέσει ο κώδικας να είναι όσο ποιο πλήρης γίνεται απαιτήται εξαντλητική συμπλήρωση απαραίτητων πεδίων (π.χ., παράμετροι, τιμές, τύποι δεδομένων, …)&lt;/p&gt;  &lt;p align="justify"&gt;Ένα πολύ σημαντικό addon (που εμείς δεν χρησιμοποιήσαμε, αλλά με την πρώτη ευκαιρία θα το αγοράσω για προσωπική χρήση) ήταν το &lt;a href="http://www.sparxsystems.com/downloads/pdf/datasheets/Visual_Studio.pdf" target="_blank"&gt;MDG Integration&lt;/a&gt;, μία καταπληκτική δυνατότητα σύνδεσης του IDE (Visual Studio ή Eclipse) με το EA. Με αυτό, χωρίς να ξέρω πολλά, υπάρχουν δυνατότητες, για Model Driven Architectures, style transformations, Real Time execution με ταυτόχρονο reflection στα UML μοντέλα. Αλλαγές στον κώδικα ή στα σχήματα γίνονται αυτόματα sychronize και πάρα πολλά άλλα, που καλώ όποιον έχει πληροφορίες να τις μοιραστεί μαζί μας.&lt;/p&gt;  &lt;p&gt;&lt;img style="display:block;float:none;margin-left:auto;margin-right:auto;" height="480" src="http://www.sparxsystems.com/images/ea_screenshots/screenshot_desktop.jpg" width="633" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.sparxsystems.com/products/ea/screenshots.html#"&gt;&lt;/a&gt;&lt;a href="http://www.sparxsystems.com/products/ea/screenshots.html#"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="display:block;float:none;margin-left:auto;margin-right:auto;" height="480" src="http://www.sparxsystems.com/images/ea_screenshots/screenshot_diagram.jpg" width="633" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.sparxsystems.com/products/ea/screenshots.html#"&gt;&lt;/a&gt;&lt;a href="http://www.sparxsystems.com/products/ea/screenshots.html#"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img style="display:block;float:none;margin-left:auto;margin-right:auto;" height="480" src="http://www.sparxsystems.com/images/ea_screenshots/screenshot_code_window.jpg" width="633" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.sparxsystems.com/products/ea/screenshots.html#"&gt;&lt;/a&gt;&lt;a href="http://www.sparxsystems.com/products/ea/screenshots.html#"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Το καλύτερο από όλα είναι ότι το Enterprise Architect Professional Edition &lt;a href="http://www.sparxsystems.com/products/ea/purchase.html" target="_blank"&gt;κοστίζει&lt;/a&gt; 200$ και αν πάρετε το academic version (με έπίδειξη φοιτητικής ταυτότητας ή κάτι άλλο που να &lt;a href="http://www.sparxsystems.com/products/academic_status_approval.html" target="_blank"&gt;πιστοποιεί&lt;/a&gt; ότι είστε φοιτητής από Πανεπιστήμιο) &lt;a href="http://www.sparxsystems.com/products/academic_pricing.html" target="_blank"&gt;η τιμή πέφτει στα 105$&lt;/a&gt; που είναι πραγματικά απίστευτο για ένα τέτοιο εργαλείο. &lt;/p&gt;  &lt;p align="justify"&gt;Το προτείνω ανεπιφύλακτα και στόχος μου είναι οτιδήποτε χρειαστεί να το κάνω με αυτό το εργαλείο, για να μπορέσω να αξιοποιήσω/κατανοήσω όσες περισσότερες δυνατότητές του μπορώ.&lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=Enterprise Architect CASE Tool για Ανάπτυξη Λογισμικού&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/03/15/enterprise-architect-case-tool.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="Enterprise Architect CASE Tool για Ανάπτυξη Λογισμικού";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/03/15/enterprise-architect-case-tool.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=46477" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="Software Engineering" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/Software+Engineering/default.aspx" /></entry><entry><title>MediaCamp2 Day 1</title><link rel="alternate" type="text/html" href="http://www.studentguru.gr/blogs/grnemo/archive/2009/03/14/mediacamp2-day-1.aspx" /><id>http://www.studentguru.gr/blogs/grnemo/archive/2009/03/14/mediacamp2-day-1.aspx</id><published>2009-03-14T19:20:00Z</published><updated>2009-03-14T19:20:00Z</updated><content type="html">&lt;p align="justify"&gt;Πάρα πολύ ωραία, σήμερα, η πρώτη μέρα στο &lt;a href="http://wiki.mediacamp.gr/" target="_blank"&gt;MediaCamp2&lt;/a&gt; (μία φοβερή &lt;a href="http://mediacampathens.wordpress.com/" target="_blank"&gt;πρωτοβουλία&lt;/a&gt; που φέρνει κοντά και ενώνει όσους ασχολούμαστε με τεχνολογία, από όποια φιλοσοφία και αν έχουμε υιοθετήσει). Ο χώρος είναι ένα από τα πιο ευχάριστα και φωτεινά μέρη που έχω δει (&lt;a href="http://www.microsoft.com/hellas/mic/default.mspx" target="_blank"&gt;Microsoft Innovation Center&lt;/a&gt;), που ευγενικά παραχώρησε η MS Hellas. &lt;img src="http://www.studentguru.gr/blogs/grnemo/14032009011_thumb_1B2748BA.jpg" title="14032009011" style="border:0px none;display:block;float:none;margin-left:auto;margin-right:auto;" alt="14032009011" width="269" border="0" height="214" /&gt;&lt;/p&gt;  &lt;p align="justify"&gt;Μοιραστήκαμε ιδέες και ενδιαφέροντα τόσο μέσω ομιλιών όσο και στα μικρά πηγαδάκια που σχηματίζονταν ανά τους ορόφους. Προσωπικά παρακολούθησα ομιλίες σχετικά με Drupal όπου ακολούθησε και ωραία συζήτηση για διάφορα Web Frameworks, για code conventions, Windows Mobile Development, WPF, Expression Design, Expression Blend, ASP.NET και την εισαγωγή σε αυτή τη νέα στροφή στο development που “ακούει” στον όρο Cloud Computing, μέσω της νέας οικογένειας υπηρεσιών της Microsoft (Windows Azure realm ;) ). &lt;/p&gt;  &lt;p align="justify"&gt;Αναμένω με αγωνία την δεύτερη μέρα, καθώς δεν υπάρχει κάτι καλύτερο από το να γνωρίζεις διαφορετικές τεχνολογίες και ταυτόχρονα έμπειρους εκφραστές τις.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;Για όσους ενδιαφέρονται να έρθουν αύριο μπορούν να περάσουν ότι ώρα θέλουν ώστε ή να παρακολουθήσουν, ή να συζητήσουν ή ακόμα και να παρουσιάσουν την δουλειά τους και ότι τους τρελλαίνει. Πληροφορίες μπορείτε να βρείτε και μέσω &lt;a href="http://www.facebook.com/home.php#/event.php?eid=55535787886" target="_blank"&gt;Facebook&lt;/a&gt;. &lt;/p&gt;&lt;div class="shareit-div"&gt;&lt;a class="a2a_dd" href="http://www.addtoany.com/share_save?linkname=MediaCamp2 Day 1&amp;amp;linkurl=http://www.studentguru.gr/blogs/grnemo/archive/2009/03/14/mediacamp2-day-1.aspx"&gt;
    &lt;img src="http://static.addtoany.com/buttons/share_save_171_16.png" width="171" height="16" border="0" alt="Share/Bookmark"/&gt;
&lt;/a&gt;
&lt;script type="text/javascript"&gt;a2a_linkname="MediaCamp2 Day 1";a2a_linkurl="http://www.studentguru.gr/blogs/grnemo/archive/2009/03/14/mediacamp2-day-1.aspx";&lt;/script&gt;
&lt;script type="text/javascript" src="http://static.addtoany.com/menu/page.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;img src="http://www.studentguru.gr/aggbug.aspx?PostID=46412" width="1" height="1"&gt;</content><author><name>grnemo</name><uri>http://www.studentguru.gr/members/grnemo.aspx</uri></author><category term="events" scheme="http://www.studentguru.gr/blogs/grnemo/archive/tags/events/default.aspx" /></entry></feed>