Twitter

In a few years we’ll all be ashamed that we used Twitter.

- Me

Azure Simplified Part 2: Using Azure Tables

Now that we’ve built a “Hello Azure!” application, lets try using Azure tables…

1. Open up VisualStudio 2008 (run as Administrator) and create a new ‘Cloud Service’ project,

image

2. Create an ASP.NET WebRole,

image

3. Add a reference to System.Data.Services.Client to the WebRole1 project.

image 

4. Add a new data connection string. To do this, go to CloudService1 –> Roles –> WebRole1 –> right click Properties –> Settings –> Add Setting. Type in ‘DataConnectionString’ and change the Type column to ‘Connection String’. Then click on the ‘…’ at the far right and choose ‘Use development storage’.

image 

 

5. Nasty hack alert! Add the following code to the WebRole.cs’s OnStart method,

public override bool OnStart() {
    DiagnosticMonitor.Start("DiagnosticsConnectionString");

    // For information on handling configuration changes
    // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
    RoleEnvironment.Changing += RoleEnvironmentChanging;

    // This code sets up a handler to update CloudStorageAccount instances when their corresponding
    // configuration settings change in the service configuration file.
    CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) => 
    {
        // Provide the configSetter with the initial value
        configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

        RoleEnvironment.Changed += (sender, arg) =>
        {
            if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                .Any((change) => (change.ConfigurationSettingName == configName))) {
                // The corresponding configuration setting has changed, propagate the value
                if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName))) {
                    RoleEnvironment.RequestRecycle();
                }
            }
        };
    });

    return base.OnStart();
}
 

6. Whew! OK, now we are ready to add our custom code,The first class you need to create is how your table rows will look like. Add a class called ‘MyTableRow.cs’ to the WebRole1 project that contains,

using Microsoft.WindowsAzure.StorageClient;

namespace WebRole1 {
    public class MyTableRow : TableServiceEntity {
        public MyTableRow(string partitionKey, string rowKey) : base(partitionKey, rowKey) { }

        // Rows need a unique partition key – so create a new guid for every row
        public MyTableRow() : this(Guid.NewGuid().ToString(), String.Empty) { }

        // My table row
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

7. Next open up Default.aspx and paste the following simple HTML controls to display the tables,

<body>
    <form id="form1" runat="server">
        <div>
            <asp:Label id="Label1" Text="Table name:" runat="server" />
            <asp:TextBox id="tablenameBox" runat="server" />
            <asp:Button ID="Button1" Text="Create Table" runat="server" />
            <br /><br />
            
            <!-- Display tables -->
            <asp:ListBox id="ListBox1" runat="server" Width="200" Height="100" />
            
            <asp:Button ID="Button3" Text="Delete Table" runat="server" />
            <br /><br />
            <asp:Label id="Label2" Text="Name:" runat="server" />
            <asp:TextBox id="rowName" runat="server" />   
            <asp:Label id="Label3" Text="Age:" runat="server" />
            <asp:TextBox id="rowAge" runat="server" />   
            <asp:Button ID="Button2" Text="Insert into Table" runat="server" />
            <br /><br />
            
            <!-- Display table contents -->
            <asp:Repeater id="Repeater1" runat="server">
                <HeaderTemplate>
                    <table border="1">
                        <tr><td><b>Name</b></td><td><b>Age</b></td></tr>
                </HeaderTemplate>
                <ItemTemplate>
                    <tr>
                      <td> <%# DataBinder.Eval(Container.DataItem, "Name") %> </td>
                      <td> <%# DataBinder.Eval(Container.DataItem, "Age") %> </td>
                    </tr>
                </ItemTemplate>
                <FooterTemplate>
                    </table>
                </FooterTemplate>
            </asp:Repeater>
        </div>    
    </form>
</body>
 

As you see, there’s nothing fancy in the HTML,  just a few buttons, a listbox to display the tables and a Repeater control to display the table contents.

7. Open Default.aspx.cs and insert the code, (you’ll want much more error checking, I’ve removed them for this example),

public partial class _Default : System.Web.UI.Page {
        
    // Manage account information
    CloudStorageAccount storageAccount = null;

    // Runtime data context
    TableServiceContext tableServiceContext = null;

    protected void Page_Load(object sender, EventArgs e) {
        // Init the contexts
        this.storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
        this.tableServiceContext = new TableServiceContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials);

        // Hook up the buttons
        this.Button1.Click += new EventHandler(CreateTableClick);
        this.Button2.Click += new EventHandler(InsertTableClick);
        this.Button3.Click += new EventHandler(DeleteTableClick);
    }

    // Create a table
    private void CreateTableClick(Object sender, EventArgs e) {
        // Create an Azure table
        storageAccount.CreateCloudTableClient().CreateTableIfNotExist(tablenameBox.Text);

        // Update the display
        this.ListBox1.Items.Clear();
        foreach (string tableName in this.storageAccount.CreateCloudTableClient().ListTables()) { 
            this.ListBox1.Items.Add(tableName); 
        }
    }

    // Insert into a table
    private void InsertTableClick(Object sender, EventArgs e) {
        // Insert into an Azure table
        this.tableServiceContext.AddObject(this.ListBox1.SelectedItem.Text, new MyTableRow() { Name = rowName.Text, Age = Int32.Parse(rowAge.Text) });
        this.tableServiceContext.SaveChanges();

        // Update the display
        ArrayList values = new ArrayList();
        foreach (MyTableRow tableRow in this.ViewTableDetails(this.ListBox1.SelectedItem.Text)) { 
            values.Add(tableRow); 
        }
        this.Repeater1.DataSource = values;
        this.Repeater1.DataBind();
    }

    // Get rows from a table
    public IEnumerable<MyTableRow> ViewTableDetails(string tableName) {
        var results = from c in this.tableServiceContext.CreateQuery<MyTableRow>(tableName) select c;

        var query = results.AsTableServiceQuery<MyTableRow>();
        var queryResults = query.Execute();
        return queryResults;
    }

    // Delete a table
    private void DeleteTableClick(object sender, EventArgs e) {
        // Delete a table from Azure
        this.storageAccount.CreateCloudTableClient().DeleteTableIfExist(this.ListBox1.SelectedItem.Text);

        // Update the display
        this.ListBox1.Items.Clear();
        foreach (string tableName in this.storageAccount.CreateCloudTableClient().ListTables()) { 
            this.ListBox1.Items.Add(tableName); 
        }
    }
}

8. Now you can run the application,

image 

 

WPF Simplified Part 15: Data Validation

Say we want to validate user input in a TextBox,

<Grid>        
    <!-- Validate this TextBox -->
    <TextBox Height="30" Width="80" Text="{Binding FirstName}" />
</Grid>

where, the TextBox is bound to an instance of the Person class,

public class Person { public string FirstName { get; set; } }

The way to do this is to associate ValidationRules with the Binding (the Text-FirstName binding). These rules validate the update of the binding source property (FirstName property) and if the update causes an error, the binding is marked as invalid.

Say we want that the TextBox’s Text (and hence the Person’s FirstName property) cannot be empty. Let’s change the Person class to throw an exception if the FirstName is null or empty,

public class Person {
    private string firstname;
    public string Firstame {
        get { return this.firstname; }
        set {
            if (string.IsNullOrEmpty(value)) {
                throw new Exception("First name cannot be null or empty");
            }
            this.firstname = value;
        }
    } 
}

Now we need a rule to associate with the binding that says, if there is an exception thrown during the update of the source property, the binding is invalid. Luckily, there is already a built-in rule for that called ExceptionValidationRule. All we need to do is associate this rule with the binding, like this,

    <TextBox Height="30" Width="80">
        <TextBox.Text>
            <Binding Path="FirstName" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <ExceptionValidationRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>

The XAML above associates a ExceptionValidationRule with the binding causing the binding to be invalidated if an exception is thrown (in our case, when the FirstName is null or empty). The validation occurs when the value of a target (TextBox’s Text dependency property) is transferred to the binding source property (Person’s FirstName property). What causes a source update depends on the value of the UpdateSourceTrigger property – “PropertyChanged” means the binding engine updates the source value on every keystroke, which means it also checks every rule in the ValidationRules collection on every keystroke. UpdateSourceTrigger could also have the value “LostFocus”, which updates the source when the target has lost focus.

We can also write our own ValidationRule,

public class CustomValidationRule : ValidationRule {
    public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
        // Say the first name can't contain a space,
        if (value.ToString().Contains(' ')) {
            return new ValidationResult(false, "No spaces allowed in FirstName");
        }
    
        return ValidationResult.ValidResult;
    }
}

and apply it to the TextBox,

    <TextBox Height="30" Width="80">
        <TextBox.Text>
            <Binding Path="FirstName" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <ExceptionValidationRule />
                    <local:CustomValidationRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
 

There are two type of built-in ValidationRules,

1. ExceptionValidationRule: Represents a rule that checks for exceptions that are thrown during the update of the binding source property.

2. DataValidationRule: Represents a rule that checks for errors that are raised by the IDataErrorInfo implementation of the source object.

Implementing IDataErrorInfo is easy enough, we implement the Person class like this,

public class Person : IDataErrorInfo {
    public string FirstName { get; set; }

    public string this[string propertyName] {
        get {
            string result = null;
            if (propertyName == "FirstName") {
                if (string.IsNullOrEmpty(this.FirstName))
                {
                    result = "Cannot be null or empty";
                }
            }
            return result;
        }
    }
 
    // Not using this
    public string Error {
        get { return null; }
    }

}

And the TextBox XAML is similar to above,

    <TextBox Height="30" Width="80">
        <TextBox.Text>
            <Binding Path="FirstName" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <DataErrorValidationRule />
                    <local:CustomValidationRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>

An alternate syntax for the above is to use the ValidatesOnDataErrors (instead of adding the DataErrorValidationRule explicitly) and ValidateOnExceptions (instead of adding the ExceptionValidationRule explicitly),

    <TextBox Height="30" Width="80">
        <TextBox.Text>
            <Binding Path="FirstName" UpdateSourceTrigger="PropertyChanged" 
                ValidatesOnDataErrors="True" ValidatesOnExceptions="True">

                <Binding.ValidationRules>
                    <local:CustomValidationRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>

We can also provide visual feedback to the user by setting the Validation.ErrorTemplate attached property of the TextBox to a custom ControlTemplate.

    <TextBox Height="30" Width="80" ToolTip="{Binding RelativeSource={RelativeSource Self}, 
                                              Path=(Validation.Errors)[0].ErrorContent}">
        <TextBox.Text>
            <Binding Path="FirstName" UpdateSourceTrigger="PropertyChanged" 
                     ValidatesOnDataErrors="True" ValidatesOnExceptions="True">
                <Binding.ValidationRules>
                    <local:CustomValidationRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
        <Validation.ErrorTemplate>
            <ControlTemplate>
                <DockPanel>
                    <AdornedElementPlaceholder Name="MyAdorner"/>
                    <TextBlock Foreground="Red" Text="{Binding ElementName=MyAdorner, 
                        Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" />
                </DockPanel>
            </ControlTemplate>
        </Validation.ErrorTemplate>
    </TextBox>

 

Digg This

WPF Simplified Part 14: INotifyPropertyChanged and ObservableCollection

When data-binding, we want changes to the source (data bound property/collection) to be reflected in the UI. Fortunately WPF gives us some easy ways to keep the UI updated of data changes.

Consider the simple XAML,

<Grid>
    <Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions>
    <!-- Data bound text block -->
    <TextBlock x:Name="MyTextBlock" Height="30" Width="110" Text="{Binding Name}" />
    <!-- Button to change to bound property -->
    <Button Grid.Row="1" Height="30" Width="110" Content="Update" Click="MyButton_Click" />
</Grid>

And the simple class,

        public class Person { public string Name { get; set; } }

We’ll data bind like this,

        Person person;

        public Window1() {
            InitializeComponent();

            person = new Person() { Name = "John" };
            
            // Data bind Window1 to the person object
            // Or we could choose to data bind to the TextBlock directly,
            // this.MyTextBlock.DataContext = person;
            this.DataContext = person;
        }

        private void MyButton_Click(object sender, RoutedEventArgs e) {
            // Change the data bound object's data bound property
            person.Name = "Locke";
        }

When you click the button, nothing happens, the UI isn’t notified that the bound property has changed. There are two ways to fix this,

1. Implement INotifyPropertyChanged:

Implement the Person class like this,

public class Person : INotifyPropertyChanged {
    private string name;

    public string Name {
        get { return name; } 
        set {
            name = value;
            NotifyPropertyChanged("Name");
        } 
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string name) {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}


Now clicking the button updates the UI and the TextBlock changes to “Locke”. See here for best practices for implementing INotifyPropertyChanged.

2. Change the property to a Dependency Property:

Implement the property (Name) backed by a dependency property (NameProperty) instead of backed by a field (name) as we previously did. Note that Person class will have to be derived from DependencyObject in this case.

public class Person : System.Windows.DependencyObject {
    public static DependencyProperty NameProperty 
                = DependencyProperty.Register("Name", typeof(string), typeof(Person));
 
    public string Name {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }
}

We have looked at how data bound properties can update the UI, let’s also look at collections, consider that XAML,

<Grid>
    <Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions>
    <!-- Data bound list view –>
    <ListView x:Name="MyListView" DisplayMemberPath="Name" />
    <!-- Button to change the bound collection -->
    <Button Grid.Row="1" Height="30" Width="80" Content="Change" Click="Button_Click" />       
</Grid>

and the Person class,

    public class Person { public string Name { get; set; } }

Let’s data bind a collection of Person to the ListView, like this,

    List<Person> people = new List<Person>()
 
    public Window1() {
        InitializeComponent();

        people.Add(new Person() { Name = "John" });
        people.Add(new Person() { Name = "Jack" });

        // Data bind to the listview,
        this.MyListView.ItemsSource = people;
    }
    private void Button_Click(object sender, RoutedEventArgs e) {
        // Change the data bound collection
        people.Add(new Person { Name = "Jacob" });
    }

When we click the button, the UI doesn’t update. This is because the collection List<> doesn’t implement INotifyPropertyChanged and INotifyCollectionChanged. Luckily, the ObservableCollection does, so simply changing people to an ObservableCollection instance does the trick.

    ObservableCollection<Person> people = new ObservableCollection<Person>();

WPF Simplified Part 13: Value Converters

In WPF, when you data bind an element’s property to a data source, if the source property type and target property type don’t match you’ll need a value converter to hook them up correctly.

Consider the following data bound TextBlock,

    <TextBlock x:Name="MyText" Text="{Binding Name}" Foreground="{Binding DisplayColor}" />

and the code behind,

    this.MyText.DataContext = new { Name = "John", DisplayColor = "BlackSmoke" };

If you try out the code and XAML above you’ll see the following error in VisualStudio’s ‘Output’ window,

System.Windows.Data Error: 6 : ‘TargetDefaultValueConverter’ converter failed to convert value ‘BlackSmoke’ (type ‘String’); fallback value will be used, if available. BindingExpression:Path=DisplayColor; DataItem=’<>f__AnonymousType0`2′ (HashCode=-850673272); target element is ‘TextBlock’ (Name=’MyText’); target property is ‘Foreground’ (type ‘Brush’) FormatException:’System.FormatException: Token is not valid.

The error is that TextBlock’s Foreground accepts a Brush type, but we bound the Foreground to a String type, hence the binding failed. What we need is a value converter that will convert a String type into a Brush type.

    [ValueConversion(typeof(string), typeof(Brush))]
    public class StringToBrushConverter : IValueConverter 
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            if (value is string) {
                string source = value as string;
                if (source == "BlackSmoke") return new SolidColorBrush(Colors.DimGray);
            }

            // Default color
            return Colors.Black;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            // To keep it simple, no need to convert back 
            return null;
        }
    }

As you can see, we’ve hand coded how a String will convert to a Brush type for our application – when the string is “BlackSmoke” we’d like the Brush to be “DimGray”. Applying this converter in XAML is simple enough,

<Grid>
    <Grid.Resources>
        <local:StringToBrushConverter x:Key="StringToBrushConverter" />
    </Grid.Resources>
       <TextBlock x:Name="MyText" Text="{Binding Name}" 
       Foreground="{Binding DisplayColor, Converter={StaticResource StringToBrushConverter}}" />
</Grid>

Thus, even though the TextBlock’s Foreground is still bound to a String type, our converter will provide the required type (Brush) to the Foreground dependency property.

WPF also has some built-in value converters, in fact, it has a built in String to Brush converter! To see this, try the following XAML,

    <TextBlock x:Name="MyText" Text="{Binding Name}" Foreground="{Binding DisplayColor}" />

with the following code behind,

    this.MyText.DataContext = new { Name = "John", DisplayColor = "Red" }; 

The text displays in red because of WPF’s built in String to Brush converter – it recognized the string ‘Red’ and converted it to the corresponding BrushColors.Red. In fact the built-in converter will recognize any of the colors in System.Windows.Media.Colors as strings, and will convert them to their corresponding Brushes. The code probably does the equivalent of the following,

    if (source == "Red") return new SolidColorBrush(Colors.Red);
    if (source == "Yellow") return new SolidColorBrush(Colors.Yellow);

    // etc.

Instantiating the converter in XAML as a resource can be cumbersome, so there is another way to use value converters. By deriving from MarkupExtension, you can use the converter directly in XAML, without using StaticResource.

    [ValueConversion(typeof(string), typeof(Brush))]
    public class StringToBrushConverter : MarkupExtension, IValueConverter 
    {
        public override object ProvideValue(IServiceProvider serviceProvider) {
            return this;
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            if (value is string) {
                string source = value as string;
                if (source == "BlackSmoke") return new SolidColorBrush(Colors.DimGray);
            }

            // Default color
            return Colors.Black;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            // To keep it simple, no need to convert back 
            return null;
        }
    }

and now you can use the converter like this,

    <TextBlock x:Name="MyText" Text="{Binding Name}" 
               Foreground="{Binding DisplayColor, Converter={local:StringToBrushConverter}}" />

WPF Simplified Part 12: Adorners

An Adorner is a new WPF construct that helps us add visual features to a UIElement. The Adorner class derives directly from FrameworkElement. So, why would you need another class to add visual effects when you can pretty much customize any WPF control using control templates and data templates? The reason is that the adorner layer lies on top of the UI element in Z-order and is helpful in some interactive scenarios to display handles and outlines.

Creating an adorner is simple, consider a simple button,

    <Button Height="30" Width="110" x:Name="MyButton" Content="Adorned Button" />

and the code behind,

    public class MyAdorner : Adorner {
        public MyAdorner(UIElement targetElement) : base(targetElement) { }

        protected override void OnRender(DrawingContext drawingContext) {
            Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);
            drawingContext.DrawRectangle(null, new Pen(Brushes.Blue, 1), adornedElementRect);
        }

    }

We have created a simple adorner that will create a border around an UIElement. The adorner constructor requires the target UIElement and will draw on top of this element. To hook up the adorner we need some more code,

    void Window1_Loaded(object sender, RoutedEventArgs e) {
        AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.MyTextBlock);
        MyAdorner myAdorner = new MyAdorner(this.MyTextBlock);
        adornerLayer.Add(myAdorner);
    }

Note that since the adorner layer is not available until the window is loaded, we’ve hooked up the code in the window’s Loaded event handler. GetAdornerLayer walks up the visual tree to find the first AdornerLayer which then can be used to render our custom adorner. The adorner layer’s location in the visual tree is determined by the AdornerDecorator element, the Window element provides an AdornerDecorator by default, which is what we added our custom adorner to. Note that this layer fills the entire window. If we want we can supply our own AdornerDecorator,

    <AdornerDecorator>
        <TextBlock x:Name="MyTextBlock" Text="Cancel" />
    </AdornerDecorator>

The adorner receives focus and input before the adorned UIElement. Also, just like we added the custom adorner to the AdornerLayer, we can remove it too, simply by,

    adornerLayer.Remove(myAdorner);

Another way to create Adorners is by providing a VisualCollection,

    public class MyAdorner : Adorner {
        // To store and manage the adorner's visual children
        VisualCollection visualChildren;

        // Custom UIElement to add to the target UIElement
        Button button = new Button();

        // Initialize the custom Adorner
        public MyAdorner(UIElement targetElement) : base(targetElement) {
            visualChildren = new VisualCollection(this);

            // Set the button properties
            button.Height = 20.0;
            button.Width = 20.0;
            button.Content = "?";

            visualChildren.Add(button);
        }

        protected override int VisualChildrenCount { get { return visualChildren.Count; } }
        protected override Visual GetVisualChild(int index) { return visualChildren[index]; }

        // Arrange the Adorner
        protected override Size ArrangeOverride(Size finalSize) {
            double desiredWidth = AdornedElement.DesiredSize.Width;
            double desiredHeight = AdornedElement.DesiredSize.Height;

            button.Arrange(new Rect((button.Width + desiredWidth) / 2, -desiredHeight, 
                                 desiredWidth, desiredHeight));
            return finalSize;
        }
    }

Combined with this xaml,

    <Grid>
        <Button Height="30" Width="110" x:Name="MyButton" Content="Adorned Button" />
    </Grid>

should render,

image

Digg This

My top 20 non-developer apps

I recently got a new laptop (Vista Ultimate x64) and was wondering what apps I would load, so here’s my top 20… 

  1. Firefox (no brainer)
  2. AVG or Avast! (anti-virus software)
  3. Adobe Reader (unfortunately can’t do without)
  4. Notepad++ (Replace the old but trusty Notepad)
  5. µTorrent (very lightweight Bittorrent client)
  6. Picasa (photo view and share)
  7. VLC (play any media file)
  8. CCleaner (system cleaning tool)
  9. Mozy (free 2GB auto backups!)
  10. KeePass (manage your online passwords) 
  11. WinZip or WinRAR (compression tools)
  12. Net Nanny (Internet Filter)
  13. Spybot Search & Destory (rid your PC of spyware)
  14. Windows Live SkyDrive (25GB free online storage)
  15. Dropbox (sync files across computers)
  16. Paint .NET (replace the aging MS Paint)
  17. Digsby (for all your IM needs)
  18. Skype (phone calls for free)
  19. Quick Media Converter (for my iPhone needs)
  20. WinDirStat (folder sizes)

(For developer apps and tools take a look at Scott Hanselman’s list).

Hello World!

The obligatory “Hello World!” first post!

About me: I work as a software developer with .NET technologies, in Seattle.

Disclaimer
The information in this weblog is provided “AS IS” with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. The opinions expressed herein are solely by own. Inappropriate comments will be deleted at the authors discretion. All code samples are provided “AS IS” without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. In addition, my thoughts and opinions often change, and as a weblog is intended to provide a semi-permanent point in time, snapshot you should not consider out of date posts to reflect my current thoughts and opinions.

Follow

Get every new post delivered to your Inbox.