Archive of entries posted by Sergey Barskiy

Extending Interfaces with Implementation

Today I was faced with an issue.  I had an interface based implementation of a specific functionality.  All classes that implemented this interface had different implementation of course.  What I had to add is ability to run certain checks on each implementation that would need to analyze the data defined in the interface and return a Boolean result of this check.

The problem was that the checks were all the same and I hated to add this check to the interface and write identical code in all implementations.  As everyone knows interfaces cannot contain implementation code though.  So, what should I do?

So, a particular .NET 3.5 feature came to my rescue.  I am referring to extension methods.  As you may or may not know extension methods are tied to a type.  Well, interface is a type too.  Here is some code to look at.

Here is the interface definition:

    public interface ISupportCustomAction

    {

        Action CustomAction { get; set; }

        void Execute();

    }

Here is my class definition that implements this interface

    public class CustomActionOne : ISupportCustomAction

    {

        #region ISupportCustomAction Members

        private Action action;

        public Action CustomAction

        {

            get

            {

                return action;

            }

            set

            {

                action = value;

            }

        }

 

        public void Execute()

        {

            // fill in the method

        }

 

 

        #endregion

    }

Finally, here is my extension method

    public static class ISupportCustomActionExtensions

    {

        public static bool Check(this ISupportCustomAction action)

        {

            if (action.CustomAction == null)

            {

                return false;

            }

            else

            {

                return true;

            }

        }

    }

Here is my test code to confirm that everything works

    class Program

    {

        static void Main(string[] args)

        {

            CustomActionOne action = new CustomActionOne();

            action.CustomAction = () => { Debug.WriteLine("Exectuted Action."); };

            Analize(action);

 

            action = new CustomActionOne();

            Analize(action);

            Console.ReadKey();

        }

 

        private static void Analize(ISupportCustomAction action)

        {

            if (action.Check())

            {

                Console.WriteLine("Can execute action");

            }

            else

            {

                Console.WriteLine("Cannot execute action");

            }

        }

    }

How useful this is?  Pretty useful in my case.  Saved me some typing and resulted in consistent coding.  My point is that is good to know what features .NET has and use them as a need arises.  As you can see I have a hybrid here of a base (abstract) class and an interface.  As a result, I am able to use features that belong to both concepts.

 

Thanks.

Community Events

I often forget about different conferences I would like to keep an eye on, so I decided to make a list of them on my blog.

Silverlight 4 + COM + SQL Server = Cool!

Today is the day to talk about COM possibilities in Silverlight 4.  One would question the titles of my post.  COM and Cool in the same sentence?  Let me proof this title to you.

First, let me take a closer look at COM.  In order to access COM, you must install Silverlight application on a local machine.  The access to COM is not enabled when a Silverlight application is run in the browser.  So, first of all you have to enable this by checking “Enable running application out of browser” checkbox in project properties.  Second of all, you have to check “Require elevated trust…” checkbox in “Out-of-browser settings” area in project properties.  Now, you are ready to install you application and test COM support.  How about Word automation:

Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
var doc = word.Documents.Add();
var paragraph = doc.Paragraphs.Add();
paragraph.Range.Text = "Some text";

Now, let’s talk about database access.  Parts of System.Data.SqlClient namespace are not exposed to COM by default.  So, to enable database access we must write an assembly that is exposed to COM that wraps database access.  To do so, check the property “Register for COM Interop” in project properties for the .NET (NOT Silverlight) based project that will fire off database queries for us.  Once the assembly is built, I can just use RegAsm to register my DLL with COM on a machine.  Of course, this would be a prerequisite to use Silverlight application for local data access.  The other prerequisite is to have .NET Runtime installed on that machine as well.  I could write an install project of course to make this process easier.

The next step is to write a Silverlight assembly that would use COM Interop similar to the one above for Word to talk to my database access .NET based assembly.

dynamic sqlDB = ComAutomationFactory.CreateObject("COMSQLClient.COMSqlDatabase");

Now the most exciting part.  I created and published the project on CodePlex that does exactly what I just talked about.  Check out the project and let me know what you think.  You can download the source code and look into the implementation details.  Here is the link to it:

http://silverlight4sqllib.codeplex.com/

Thanks.

The MSDN Southern Fried Roadshow

Glen Gordon, our local evangelist is doing another road show.  Here are the event details.

Thursday, February 25, 2010 1:00 PM – Thursday, February 25, 2010 5:00 PM Eastern Time (US & Canada)
Welcome Time: 12:30 PM

Atlanta Marriot Alpharetta

5750 Windward Pkwy
Alpharetta Georgia 30005
United States

Language(s):
English.

Product(s):
Azure Services Platform, Microsoft technologies, Windows and Windows 7.

Audience(s):
Pro Dev/Programmer.

Presenter(s):
Glen Gordon, Joe Healy

Event Overview

MSDN Events presents: Take Your Applications Sky High with Cloud Computing and the Windows Azure Platform

Join your local MSDN Events team as we take a deep dive into cloud computing and the Windows Azure Platform. We’ll start with a developer-focused overview of this new platform and the cloud computing services that can be used either together or independently to build highly scalable applications. As the day unfolds, we’ll explore data storage, SQL Azure, and the basics of deployment with Windows Azure. Register today for these free, live sessions in your local area.

If you register and attend this event, you will be placed in a raffle to win a chance to bring home one (1) free copy of Windows 7 – you could be the lucky winner! Register today!

SESSION 1: Overview of Cloud Computing and Windows Azure

The Windows Azure platform is a set of high-performance cloud computing services that can be used together or independently and enable developers to leverage existing skills and familiar tools to develop cloud applications. In this session, we’ll provide a developer-focused overview of this new online service computing platform. We’ll explore the components, key features and real day-to-day benefits of Windows Azure.

Highlights include:

· What is cloud computing?

· Running web and web service applications in the cloud

· Using the Windows Azure and local developer cloud fabric

· Getting started – tools, SDKs and accounts

· Writing applications for Windows Azure

SESSION 2: Survey of Windows Azure Platform Storage Options

Durable data storage is a key component of any cloud computing offering. The Windows Azure Platform offers many options, which can be used alone or in combination. Windows Azure itself offers ready-to-use and lightweight storage in the form of tables, blobs, and queues. Another choice for storage is SQL Azure, a true relational database in the cloud. In this session, we’ll explore the highlights of these implementations and how to both create and use storage in each form. We’ll give you guidance on choosing the right forms of storage for your application scenarios.

Highlights include:

· Understanding table & blob storage

· Programming against table & blob storage

· Working with queue storage

· Managing credentials and connection strings

· Scaling and configuration

· Understanding SQL Azure databases versus local SQL Server databases

· SQL Azure firewall, logins and passwords

· Database creation, deployments and migrations

· Database management using SQL Management Studio

· Programming against SQL Azure databases

SESSION 3: Going Live with your Azure Solution

Windows Azure features a powerful, yet simple deployment model. By focusing on your application and abstracting away the infrastructure details, you can deploy almost any app with minimal fuss. In this session, we’ll walk you through the basics of Windows Azure deployment, including site monitoring, diagnostics and performance issues.

Highlights include:

· Start-to-Finish Visual Studio demonstration of a realistic XML data driven business web site from the desktop to the cloud.

· Windows Azure Deployments

· Start-to-Finish Visual Studio demonstration of a realistic SQL Server data driven business web site from the desktop to the cloud.

· Configuration of your application in the cloud

· Guidance and Suggestions to ensure your success

*Be sure to learn more about the TechNet event happening on the same day at the same location from 8:30am–12:00pm. If you are interested in attending, please register separately for that event here: http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439495&Culture=en-US

Registration Options

Event ID:
1032439974

Here is the link to this event:

http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032439974&Culture=en-US

Entity Framework 4.0 and Multiple Data Contexts

In the EF version 1.0, there was a problem when one would try to update multiple contexts as part of a single transaction.  For example, I can use Transaction Scope, the update one context, then second context.  Here is sample code to illustrate:

 

using (TransactionScope scope = new TransactionScope())
{
    try
    {
        using (RolodexEntities context = new RolodexEntities())
        {
            context.Connection.Open();

            Company company = new Company();
            company.CompanyName = "Test 1";
            company.DateAdded = DateTime.Today;
            context.AddToCompanies(company);
            context.SaveChanges();

            using (RolodexEntities context2 = new RolodexEntities(context.Connection as EntityConnection))
            {
                Company company2 = new Company();
                company2.CompanyName = "Test 1";
                company2.DateAdded = DateTime.Today;
                context2.AddToCompanies(company2);
                context2.SaveChanges();
            }
        }

        scope.Complete();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

This code in version 1.0 would throw an exception when second context’s constructor was called.  The exception was quite obscure and was referring to the fact that the connection was already open.  This was actually correct, but that was the whole reason I was passing in the connection.  I was trying to make sure that my transaction would not get promoted to Distributed Transactions Coordinator.  The transaction would always get promoted as soon as there are multiple SQL Server connections used within using scope/.end using scope code block.  So, in version 1.0 MSDTC would be required in the code above.

This issue still exists in EF 4.0.  You can vote to fix the issue here : https://connect.microsoft.com/data/feedback/details/533240/cannot-share-a-store-connection-between-multiple-contexts-in-order-to-avoid-dtc-promotion

Here is the code that confirms the problem:

using (TransactionScope scope = new TransactionScope())
{
    try
    {
        using (RolodexEntities context = new RolodexEntities())
        {
            context.Connection.Open();

            Company company = new Company();
            company.CompanyName = "Test 11";
            company.DateAdded = DateTime.Today;
            context.AddToCompanies(company);
            context.SaveChanges();

            RolodexEntities1 contextTemp = new RolodexEntities1();
            MetadataWorkspace space = (contextTemp.Connection as EntityConnection).GetMetadataWorkspace();
            EntityConnection connection = new EntityConnection(space, (context.Connection as EntityConnection).StoreConnection);

            using (RolodexEntities1 context2 = new RolodexEntities1(connection))
            {
                User user = new User();
                user.UserName = "test";
                user.Role = "User";
                context2.AddToUsers(user);
                context2.SaveChanges();
            }
        }

        scope.Complete();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Please feel free to ask any questions on this subject.

Silverlight, MVVM and Animations

Yesterday I was asked about a way to play animations in MVVM environment.

So, I gave this some thought today, and came up with a few ideas.

First, and the easiest way is to separate ViewModel from animation by attaching an animation to a behavior.  Here is how we would write the behavior:

public class MVVMSimpleAnimationBehavior : TargetedTriggerAction<UIElement>

{

    protected override void Invoke(object parameter)

    {

        RunAnimation();

    }

 

    public Storyboard AnimationStoryBoard

    {

        get { return (Storyboard)GetValue(AnimationStoryBoardProperty); }

        set { SetValue(AnimationStoryBoardProperty, value); }

    }

 

    public static readonly DependencyProperty AnimationStoryBoardProperty =

        DependencyProperty.Register("AnimationStoryBoard", typeof(Storyboard), typeof(MVVMSimpleAnimationBehavior), new PropertyMetadata(null));

 

 

    private void RunAnimation()

    {

        if (AnimationStoryBoard != null)

        {

            AnimationStoryBoard.Begin();

        }

    }

}

 

Pretty simple approach.  Here is how would use animation in the XAML:

<Button Content="Behavior Test" Grid.Column="1">

    <i:Interaction.Triggers>

        <i:EventTrigger EventName="Click">

            <local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}"/>

        </i:EventTrigger>

    </i:Interaction.Triggers>

</Button>

Now, I want to complicate the story a little bit.  I really want to trigger an animation in the UI via an event in my model.  I am going to start with a sample ViewModel.  I want to have an event there that I will later use as a trigger for my animation.  Here is what my ViewModel would look like:

public class SampleModel: INotifyPropertyChanged

{

 

    public event EventHandler StartAnimation;

 

    protected virtual void OnStartAnimation()

    {

        if (StartAnimation != null)

        {

            StartAnimation(this, EventArgs.Empty);

        }

    }

 

    public void RaiseEvent()

    {

        OnStartAnimation();

    }

 

    #region INotifyPropertyChanged Members

 

    public event PropertyChangedEventHandler PropertyChanged;

 

    protected virtual void OnPropertyChanged(string propertyName)

    {

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }

    }

 

    #endregion

}

My event is called StartAnimation.  Now it is time to develop a more complicate behavior to support my event driven animation from ViewModel.  I am going to actually combine new functionality with the simple behavior about and have multi-functional useful object.  Here is what the final product looks like:

using System;

using System.Windows.Interactivity;

using System.Windows;

using System.Windows.Media.Animation;

using System.ComponentModel;

using System.Reflection;

 

 

namespace SLMVVMAnimationBehavior

{

    public class MVVMAnimationBehavior : TargetedTriggerAction<UIElement>

    {

        private EventInfo info;

        protected override void Invoke(object parameter)

        {

            RunAnimation(this, EventArgs.Empty);

        }

 

        public Storyboard AnimationStoryBoard

        {

            get { return (Storyboard)GetValue(AnimationStoryBoardProperty); }

            set { SetValue(AnimationStoryBoardProperty, value); }

        }

 

        public static readonly DependencyProperty AnimationStoryBoardProperty =

            DependencyProperty.Register("AnimationStoryBoard", typeof(Storyboard), typeof(MVVMAnimationBehavior), new PropertyMetadata(null));

 

        public string EventName

        {

            get { return (string)GetValue(EventNameProperty); }

            set { SetValue(EventNameProperty, value); }

        }

 

        public static readonly DependencyProperty EventNameProperty =

            DependencyProperty.Register("EventName", typeof(string), typeof(MVVMAnimationBehavior), new PropertyMetadata(HandlModelChanged));

 

 

        public object Model

        {

            get { return GetValue(ModelProperty); }

            set { SetValue(ModelProperty, value); }

        }

 

        public static readonly DependencyProperty ModelProperty =

            DependencyProperty.Register("Model", typeof(object), typeof(MVVMAnimationBehavior), new PropertyMetadata(HandlModelChanged));

 

        private static void HandlModelChanged(object sender, DependencyPropertyChangedEventArgs e)

        {

            MVVMAnimationBehavior behavior = sender as MVVMAnimationBehavior;

            object model = behavior.Model;

            if (behavior.info != null)

            {

                behavior.info.RemoveEventHandler(model, Delegate.CreateDelegate(typeof(EventHandler), behavior, "RunAnimation"));

            }

            if (model != null && !string.IsNullOrEmpty(behavior.EventName))

            {

                behavior.info = model.GetType().GetEvent(behavior.EventName);

                behavior.info.AddEventHandler(model, Delegate.CreateDelegate(typeof(EventHandler), behavior, "RunAnimation"));

 

            }

        }

 

        private void RunAnimation(object sender, EventArgs e)

        {

            if (AnimationStoryBoard != null)

            {

                AnimationStoryBoard.Begin();

            }

        }

    }

}

 

 

As you can see, I added two mode dependency properties – one for event name that will trigger the animation, the other one for ViewModel ( I actually called it model).  Now the tricky part is to use a bit of reflection to attach an event handler to the event on my model.  This is done in HandlModelChanged routine that is called when Model or Event name is set.  I am getting an event, and attaching a handler to it.  The actual handler is located inside the behavior itself – RunAnimation method.  Here is what my fianl XAML looks like that is testing both animation approaches:

<UserControl x:Class="SLMVVMAnimationBehavior.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    xmlns:local="clr-namespace:SLMVVMAnimationBehavior"

    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

    <UserControl.Resources>

        <Storyboard x:Name="TestStoryboard">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="textBlock" Storyboard.TargetProperty="(TextBlock.FontSize)">

                <EasingDoubleKeyFrame KeyTime="00:00:00.1000000" Value="24"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.2000000" Value="21.333"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.3000000" Value="18.667"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.4000000" Value="16"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="13.333"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.6000000" Value="16"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.7000000" Value="18.667"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.8000000" Value="21.333"/>

                <EasingDoubleKeyFrame KeyTime="00:00:00.9000000" Value="24"/>

                <EasingDoubleKeyFrame KeyTime="00:00:01" Value="26.667"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

        <local:SampleModel x:Key="CurrentModel" />

        <local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}" Model="{StaticResource CurrentModel}" x:Key="Animation" EventName="StartAnimation"/>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="#FFF3EEEE" DataContext="{Binding Source={StaticResource CurrentModel}}">

        <Grid>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="Auto"/>

                <ColumnDefinition Width="Auto"/>

                <ColumnDefinition/>

            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>

                <RowDefinition Height="Auto"/>

                <RowDefinition/>

            </Grid.RowDefinitions>

            <Button x:Name="TestButton" Content="Click To Start Animation" d:LayoutOverrides="Height" HorizontalAlignment="Left" Click="TestButton_Click"/>

            <Button Content="Behavior Test" Grid.Column="1">

                <i:Interaction.Triggers>

                    <i:EventTrigger EventName="Click">

                        <local:MVVMAnimationBehavior AnimationStoryBoard="{StaticResource TestStoryboard}"/>

                    </i:EventTrigger>

                </i:Interaction.Triggers>

            </Button>

            <TextBlock x:Name="textBlock" Margin="0,0,0,6" Text="Sample Text" TextWrapping="Wrap" d:LayoutOverrides="Width, Height" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26.667"/>

        </Grid>

 

    </Grid>

</UserControl>

 

To summarize, I illustrate a couple of approaches to trigger animations in MVVM environment.  Of course, there is always code-behind, but many developers frown at this approach..

Please let me know if you have any questions.

WCF RIA Services Validation

Today I am continuing exploring WCF RIA Services.  I am going to discuss validation in RIA Services.

Any business application needs to validate user input.  I am going to start with a simple case.  In my sample application a user can enter a company information.  I would like to setup RIA Services to force the user to enter a company name before he or she can save the company.  In order to do so I am going to use Data Annotations.  First of all, I need to add a reference to System.ComponentModel.DataAnnotations DLL to all my projects.  RIA Services project should already have the reference. 

Now I need to edit my metadata file that corresponds to my data model under .NET version of RIA Services.  In my case it is RolodexDomainService.metadata.cs file in SilverlightRIAServicesLibrary.Web project.  In that file I need to find Companies class, then location company name property, then decorate the property with required attribute.  At the same time we will also put a limit on how many characters a user can enter:

[Required]

[StringLength(30)]

public string CompanyName;

 

If we want to see the results of our changes, we can run the application, then clear company name for an existing comp-any, then tab out of company name field.  Here we get visual feedback that our input was not valid:

image

Now, let’s create custom validation.  Fir example, I am going to force the date added to be no less that 1/1/2000.  To do this I will write a custom validation class like so:

public static class ValidationHelper

{

    public static ValidationResult DateAddedCheck(DateTime date)

    {

        ValidationResult result;

        if (date > new DateTime(2000, 1, 1))

        {

            result = new ValidationResult("");

        }

        else

        {

            result = new ValidationResult("Date is not valid");

        }

 

        return result;

    }

}

Validation method that I wrote is a static member.  It follows a specific signature that RIA Services requires.  For example, it returns Validation Result that contains specific information that validation infrastructure of RIA Services can parse.  Overall code is fairly simple.

In order to make this class available on the Silverlight side, I must include my validation class into Silverlight version of RIA Services library – SilverlightRIAServicesLibrary project in my case.  In order not to duplicate the code, I will include the same class as a link.  I right-click on the project, choose add existing item, navigate to my class, then click on down arrow on Add button, and select Add As Link.  Now I have the same validation on both .NET and Silverlight side.  To confirm, I just build and run the application.  Here is what my DateAdded attributes look like:

[Required]

[CustomValidation(typeof(ValidationHelper), "DateAddedCheck", ErrorMessage = "Date is not valid")]

public DateTime DateAdded;

On important thing to mention that in  order to see validation error in UI, we need to update our Binding to look as following:

<TextBox x:Name="CompanyNameTextbox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" Margin="6,6,6,6" Text="{Binding Path=CompanyName, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnExceptions=True}" VerticalAlignment="Center"/>

There is one important thing to notice.  If you look at Silverlight side generated code, you will notice that validation occurs before the property value is set.  As a result, you cannot rely on property value being set if a validation exception is thrown.

Now, let’s look at saving code that we had to modify in order to validate user input.  Here is what it looks like:

try

{

    Validator.ValidateObject(this.Model, new ValidationContext(this.Model, null, null), true);

    if (this.Model.HasChanges)

    {

        ShowPleaseWaitMessage();

        _context.SubmitChanges(HandleSave, null);

    }

}

catch (ValidationException ex)

{

    MessageBox.Show(ex.Message);

}

Not really the cleanest code because we have to rely on exceptions being thrown. 

I covered all key area of validation, but there is more for you to explore.  Please let me know if you have any questions.

Windows Azure

I just want to relay Microsoft’s new offer to everyone.  Windows Azure is now offered for free for a limited time.  This is an introductory offer to get more people to use new cloud platform from Microsoft.  Please see this link for details.

Speaking at Atlanta .NET Users Group

I spoke at Atlanta.NET Users Group yesterday, My topic was Azure Step-by-Step.

I talked about why someone would use Windows and SQL Azure, then I built a Silverlight application from scratch.  The application was designed to run in Windows Azure and use SQL Azure as database.  I demonstrated how to get maximum code re-use between traditional .NET web application and the same application developed for Azure.  At the end, I had an application that could run on either platform with just web.config change.

You can download the zip file with PowerPoint slides with useful links as well as the sample project I built here.

Please let me know if you have any questions.

RIA Services (Cont.)

In this post I will cover the update process.

I am going to recap where I left off in the last post on RIA Services.  The last step was to retrieved based on ID from a read only company object.  Once this object is obtained in the VIewModel, we can create a screen to edit a company.

Here is how I am getting the company by ID in the ViewModel class:

var

companyQuery = _context.GetCompanyQuery(_companyID);

 

_context.Load<Companies>(companyQuery, (o1) =>

 

{

 

    HidePleaseWaitMessage();

 

    if (o.Error != null)

 

    {

 

        ErrorHandler.HandleException(o.Error);

 

    }

 

    else

 

    {

 

        this.Model = o1.Entities.First() as Companies;

 

    }

 

}, null);

Now that I have my Model property set, I can create a user control to edit the company.  Here is the part of the XAML for the edit form that shows the binding:

<UserControl x:Class

=”Rolodex.Silverlight.Views.CompanyEditView”

 

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

 

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

 

    xmlns:controls=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”

 

    xmlns:input=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls”

 

    xmlns:cal=”clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation”

 

    xmlns:core=”clr-namespace:Rolodex.Silverlight.Core”

 

    >

 

    <UserControl.Resources

>

 

       

 

    </UserControl.Resources

>

 

    <Grid x:Name

=”LayoutRoot”>

 

        <Grid.RowDefinitions

>

 

            <RowDefinition Height

=”*”/>

 

            <RowDefinition Height

=”Auto”/>

 

        </Grid.RowDefinitions

>

 

        <Grid x:Name=”EditGrid” DataContext=”{Binding Model

}”>

 

            <Grid.RowDefinitions

>

 

                <RowDefinition Height

=”35″/>

 

                <RowDefinition Height

=”35″/>

 

                <RowDefinition Height

=”1*”/>

 

                <RowDefinition Height

=”35″/>

 

                <RowDefinition Height

=”1*”/>

 

                <RowDefinition Height

=”35″/>

 

            </Grid.RowDefinitions

>

 

            <Grid.ColumnDefinitions

>

 

                <ColumnDefinition Width

=”Auto”/>

 

                <ColumnDefinition Width

=”200″/>

 

                <ColumnDefinition Width

=”*”/>

 

            </Grid.ColumnDefinitions

>

 

            <TextBlock Text=”Company Name:” TextAlignment=”Right” HorizontalAlignment=”Right” Grid.Column=”0″ Grid.Row=”0″ Margin=”6,6,6,6″ VerticalAlignment

=”Center”/>

 

            <TextBox x:Name=”CompanyNameTextbox” Grid.Column=”1″ Grid.Row=”0″ HorizontalAlignment=”Stretch” Margin=”6,6,6,6″ Text=”{Binding Path=CompanyName, Mode=TwoWay}” VerticalAlignment

=”Center”/>

 

            <TextBlock Text=”Date Added:” TextAlignment=”Right” HorizontalAlignment=”Right” Grid.Column=”0″ Grid.Row=”1″ Margin=”6,6,6,6″ VerticalAlignment

=”Center”/>

 

            <input:DatePicker x:Name=”DateAddedTextbox” SelectedDate=”{Binding DateAdded, Mode=TwoWay}” Grid.Column=”1″ Grid.Row=”1″ HorizontalAlignment=”Stretch” Margin=”6,6,6,6″ VerticalAlignment=”Center”/>

So far, I have an instance of a Companies object that is bound to the data context of my user control.  At this point a user can edit company name and date added fields.  Logically, the next thing a user would want to do is to save his changed – the nerve of him :-)

So, let’s take a look at the Save command in our view model object.

 

protected

override void BeginSave()

 

{

 

    ShowPleaseWaitMessage();

 

    _context.SubmitChanges(HandleSave, null);

 

}

 

 

 

private

void HandleSave(SubmitOperation operation)

 

{

 

    HidePleaseWaitMessage();

 

    if (operation.Error != null)

 

    {

 

        ErrorHandler.HandleException(operation.Error);

 

    }

 

}

Save is a two step process because all communication in Silverlight is asynchronous.  We are starting the save process in BeginSave, and we are checking for errors in HandleSave methods respectively.  The key part to this process is client side context of RIA Services that keeps track of all the changes that the user is making after the object has been initially retrieved via a call to the server.  The key work is done by the domain service object – LinqToEntitiesDomainService<RolodexEntities> in our case.  We can look at this code generated by the RIA Services wizard by looking at RolodexDomainService.cs class in my case.  There is a bug in current CTP that causes update to parent and child objects not being flushed properly.  In my case I have Companies object that contains a list of ComanyContacts objects.  Generated code has check for EntityState in UpdateCompanyContacts method that I had to remove to get the process to work.  Here is the final version of key methods of the Domain service class:

public

void UpdateCompanies(Companies currentCompanies)

 

{

 

    this.ObjectContext.AttachAsModified(currentCompanies, this.ChangeSet.GetOriginal(currentCompanies));

 

}

public

void UpdateCompanyContacts(CompanyContacts currentCompanyContacts)

 

{

 

    this.ObjectContext.AttachAsModified(currentCompanyContacts, this.ChangeSet.GetOriginal(currentCompanyContacts));

 

}

So, after this step all parts of the process are working – I can update companies and contacts.

Please email me any questions,

Velocity Presentation

As I mentioned previously, I presented on the topic of Velocity at the Atlanta Leading Edge Microsoft Users Group on Tuesday, January 19th.

The talk went pretty well, we had a lot of technical questions.  I really enjoyed this presentation, as I am always excited to speak on a new topic that I have not covered previously. 

You can download materials here.

 

Please let me know if you have any questions.

RIA Services (Cont.)

I am going to continue exploring the topic of RIA services and Silverlight.  I thought I was going to get into updates in this post, but there are a few topics I would like to cover first.  I am going to try to get to updates in the next post.

Today, I am going to explore two more topics.  I am going to cover extending RIA Services DomainContext with custom classes and working on including child objects when fetching a parent object using Entity Framework and RIA Services.

 

First, I am going to extend my DomainContext with a custom class.  In my case I have Company Object/Table with a number of columns.  In my Silverlight application I would like to have a list of companies that shows only company name.  When a user selected one company, I would like to fetch full company object with company contacts child object.  If I were to use the method that the wizard built for me – public IQueryable<Companies> GetCompanies(),I would get the full object with all columns.  So, I am going to build a custom class that only has company ID and name:

    public class ReadOnlyCompany

    {

        [Key]

        public int CompanyId { internal set; get; }

        public string CompanyName { internal set; get; }

    }

 

I am going to add this class to RIA Service project on .NET side (SilverlightRIAServicesLibrary.Web project in my case).  As you notice I did not have to decorate my class with DataContract attribute or decorate properties with DataMember attribute.  We do not actually need to do this, as RIA Services will take care of all that for us.  I do however need to use Key attribute or I would get a compile time error.  Each object is required to have a key (primary key) property.  Next step is to write a method in DomainService (RoldexDomainService in my case) class.  Here is what this would look like:

        public List<ReadOnlyCompany> GetReadOnlyCompanies()

        {

            return (from oneCompany in this.ObjectContext.Companies

                    orderby oneCompany.CompanyName

                    select new ReadOnlyCompany()

                    {

                        CompanyId = oneCompany.CompanyId,

                        CompanyName = oneCompany.CompanyName

                    }).ToList<ReadOnlyCompany>();

        }

 

Even though I return List object here, but RIA Services will actually return ReadOnlyObservableCollection<ReadOnlyCompany> on Silverlight side.  You have to remember that when you cast return value for RIA Services call to a specific object.  Here is what this call would look like on Silverlight side:

        private void GetCompaniesList()

        {

            ShowPleaseWaitMessage();

            var query = _context.GetReadOnlyCompaniesQuery();

 

            _context.Load<ReadOnlyCompany>(query, LoadBehavior.RefreshCurrent, (o) =>

            {

                HidePleaseWaitMessage();

                if (o.Error != null)

                    ErrorHandler.HandleException(o.Error);

                else

                {

                    this.Model = o.Entities as ReadOnlyObservableCollection<ReadOnlyCompany>;

                }

                    HidePleaseWaitMessage();

            }, null); ;

 

        }

Here I am putting up a please wait window, fire a query and interpret the results.  As I mention before, my next step is to get full Company object based on selected ID.  Again, I am adding a new method to DomainService class on .NET side:

        public Companies GetCompany(int companyID)

        {

            var returnValue = this.ObjectContext.Companies

                .Include("CompanyContacts")

                .Include("CompanyContacts.CompanyContactPhones")

                .Where(one => one.CompanyId == companyID).FirstOrDefault();

            return returnValue;

        }

Now, let’s see what this call looks like on Silverlight side.  This also demonstrates the use of parameters:

var companyQuery = _context.GetCompanyQuery(_companyID);

_context.Load<Companies>(companyQuery, (o1) =>

{

    HidePleaseWaitMessage();

    if (o.Error != null)

    {

        ErrorHandler.HandleException(o.Error);

    }

    else

    {

        this.Model = o1.Entities.First() as Companies;

    }

}, null);

As you can see, RIA services build us a query that already has the same company ID parameter for us.  Pretty cool!  However, if I look at return value (Companies object), I will notice that contacts property is actually null even though I did add .Include statement to my custom Entity Framework based method.  To get this to work, I have to modify the metadata class that RIA Services generated(RolodexDomainService.metadata.cs in my case).  I need to open this class file and look for Companies object.  I will find public EntityCollection<CompanyContactPhones> CompanyContactPhones property in it.  To get RIA Services to include child collection, I need to add Include attribute here as well:

[Include]

public EntityCollection<CompanyContactPhones> CompanyContactPhones;

I would have to take the same step to include phones collection for each contact.  If I run my code again, I will not get Company object with a list of Contacts, each containing a list of Phones.

I will try to cover update in my next post.

Thank you and do not hesitate to ask questions.

Talk at GGMUG

As always I had fun presenting at Gwinnett Georgia Microsoft Users Group on Thursday.  The subject of my talk was “Getting started with SQL Azure”.  I documented all the steps in this blog post.  There are also useful links that I mentioned in this post to help you get started.

There are many advantages to use SQL Azure.  Number of reason is probably the fact that one can eliminate the need to house expensive hardware and software on premises.  As long as you are fine with living with certain limitations of SQL Azure compared to SQL Server 2008, you can take advantage of this great technology.  The primary limitation is probably the size of the database.  You cannot have a database bigger than 10 GB.

Feel free to ask any questions on the topic.

Microsoft MVP

I have just been selected to receive the Microsoft MVP award!  This is an awesome news!  I feel honored and humbled that Microsoft recognized my efforts in learning Microsoft technologies and being active in local Microsoft oriented developer communities, user groups and events.  At the risk of making cliché comments, I would like to recognize a few people and organizations that encouraged me to strive to do my best.

As much as I learned by working at Horizon Software, there is no way I would have gotten where I am without Magenic Technologies.  This the most awesome company to work for.  Great environment and great people too numerous to mention encouraged me to work hard every day.  Participating in local users group has been invaluable experience for me as well.  I have met many people smarter than me over the last number of years that helped me out a lot.  Special thanks to Glen Gordon, local Microsoft developer evangelist for nominating me.  I am very much looking forward to many exciting years learning and (hopefully) teaching Microsoft technologies.

Getting Started with WCF RIA Services

I know many posts have been written on this subject by many people, but I am writing this one mostly for myself.  I find it very useful to type my thoughts on any subject and create a sample project to help me commit more information to memory.  So, here it goes.

What you need to get started.

  1. Visual Studio 2008 SP 1 (You can use 2010 as well)
  2. WCF RIA Services Beta for Visual Studio 2008 SP1 (http://www.microsoft.com/downloads/details.aspx?FamilyID=76bb3a07-3846-4564-b0c3-27972bcaabce&displaylang=en)

Here is what needs to be done next.

Create new Silverlight project.  To do so just create new project and select Silverlight.  Make sure to create a host web site as well.

image

On the next wizard screen select an option to create new host web site and enable .NET RIA Services.

image

 

Now, add new project to the solution, selecting WCF RIA Services Library under Silverlight projects.

image

Here is what your solution will look like:

image

Go ahead and delete Class1.cs from both RIAServicesLibrary projects.  What you see here are two new project.  RIAServicesClassLibrary1.Web will be server side project, the other RIA project is client side.  Now you need to establish references.  Add a project reference to SilverlightApplication1 and point it to RIASerivcesLibrary1 project.  Add a project reference to SilverlightApplication1.Web and point it to RIAServicesLirbary1.Web.

 

Now you need to create Entity Framework item inside the RIAServicesLibrary1.Web project.

image

Follow all the step of that wizard, generating a model from the database and pointing to a new or existing server connection.  You can select all or some tables from a database.

Go ahead and build your solution now.

Now add another new item to RIAServicesLirbary1.Web project and select Domain Service Class

image

Select the Entity Framework model you just created in that wizard and select tables you would like to use on the client.

image

Rebuild the solution once more to generate Silverlight side hidden classes that support RIA Services.  You can see that code if you click on Show All Files button in Solution Explorer:

image

Now, I am going to test the setup by adding the following code to MainPage.xaml.cs.  I am going to simulate the login process by getting a specific user from my Users table and checking the password:

using System.Windows.Ria;

using System.Linq;

public partial class MainPage : UserControl

    {

        DomainService1 _context = new DomainService1();

        public MainPage()

        {

            InitializeComponent();

            Login();

        }

 

        private void Login()

        {

            var query = _context.GetUsersQuery().Where(one => one.UserName == "admin");

 

            _context.Load<Users>(query, LoadBehavior.RefreshCurrent, (o) =>

            {

                if (o.Error != null)

                    MessageBox.Show(o.Error.ToString());

                else

                {

                    if ((o.AllEntities.Count() == 1) &&

                        (o.AllEntities.First() as Users).Password == "admin")

                    {

                        MessageBox.Show("Login successfull.");

                    }

 

                    else

                    {

                        MessageBox.Show("Login failed.");

                    }

                }

            }, null); ;

        }

    }

Next we need to update web.config in SilverlightApplication1.Web project using app.config from RIAServicesLirbary1.Web project as an example.  Make sure to paste all appropriate data into correct places:

<?xml version="1.0" encoding="utf-8"?>

<configuration>

    <connectionStrings>

        <add name="RolodexEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.\sql2008;Initial Catalog=Rolodex;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />

    </connectionStrings>

    <system.serviceModel>

        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

    </system.serviceModel>

    <system.web>

        <httpModules>

            <add name="DomainServiceModule" type="System.Web.Ria.Services.DomainServiceHttpModule, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

        </httpModules>

    </system.web>

</configuration>

Run the application now to confirm that everything is working properly.  In the next post I will explore the subject of updating the data on the server.

AppFabric Caching (Velocity) and Versioning

To continue on the topic of Velocity, I will explore versioning today.

As I showed previously, you can use DataCache.Add method to add an item to cache.  This, of course, requires that this item’s key was not to be found in the cache already, or an exception will be thrown.  This puts a damper on versioning,  So, let’s look at a different method – Put.

You can use Put method to add/replace an item in cache.  If a key already exists, the item will be replaced, otherwise it will be added.

// add an item to cache

CachablePerson person1 = new CachablePerson();

person1.FirstName = "Version1";

DataCacheItemVersion version1 = _defaultCache.Put("personwithversion", person1);

 

 

Now, I will explore versioning of items.  In order to control versioning, I will use GetAndLock method to get an item from cache while locking it to ensure safe updates.  I will update a property of an object I got from cache, then I will put it back into cache.

// get an item and lock it

DataCacheLockHandle handle;

CachablePerson temp = _defaultCache.GetAndLock("personwithversion", TimeSpan.FromSeconds(1), out handle, true) as CachablePerson;

/update an item

temp.FirstName = "Version2";

//put it back and get the new version

DataCacheItemVersion version2 = _defaultCache.PutAndUnlock("personwithversion", temp, handle);

Now I will version that versioning actually works by getting both initial and new items

// get initial item

CachablePerson ver1 = (CachablePerson)_defaultCache.Get("personwithversion");

// get the item with version 2

CachablePerson ver2 = (CachablePerson)_defaultCache.GetIfNewer("personwithversion", ref version1);

To proof that the process worked, I will output the results to a window or console.  In my case ver1.FirstName is Version1 and ver2.FirstName is Version2 which is what is expected.

In this post I looked at the Put method that makes it easier to put items into cache without worrying if an item with the same key already exists.  I also looked at the way to maintain many versioned items with the same key in cache in case versioning is important to the consuming application.

You can download the updated initial sample here.

Upcoming talks

Somehow (I am not exactly sure how) I ended up with a lot of talks that I am doing in January.  Between that and two projects I am working on simultaneously at Magenic, I have been extremely busy lately.  Those two projects will continue through end of January.

In January I will talking at Gwinnett Georgia Microsoft Users Group on SQL Azure, at Atlanta Leading Edge Microsoft Users Group on Velocity, and at Atlanta .NET Users Group on building an Azure application step-by-step.  I am also wiring an article on Entity Framework for a magazine that is due on December 31st.  Also, I am going on vacation this Saturday – my wife and I are talking our kids to Washington, DC.

I will probably be doing much blogging for a few weeks as a result.

Could I possibly have more fun than this?  Not likely.

Getting Started with Velocity (AppFabric Caching Library)

I have worked through my first Velocity project today, and I would like to blog about  the steps necessary to use caching.

First, you should read my previous post and install AppFabric on your machine.

I used Visual Studio 2010 beta 2 to create the solution.  You can download the solution here.  I create WPF project in order to prove that caching is not limited to web applications, although web farm would probably be an ideal application for caching.  Once project is created, I added references to DLLs for Velocity.  On my machine they were located in C:\Windows\System32\ApplicationServerExtensions.  Two DLLs I needed were CacheBaseLibrary.dll and  ClientLibrary.dll.  They contain key classes that can be used to utilize caching.  I could not add them directly from that folder, I was getting an error from Add Reference dialog.  So, I copied them into a folder under my Solution (“Bin” folder).

Then I added a complex class that I intended to cache.  I wanted to prove to myself that complex object graphs are OK since all the demos I saw just used strings.  Here is the class I used:

 

    public class CachablePerson

    {

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public List<CachableAddress> Addresses { get; set; }

        public CachablePerson()

        {

            FirstName = "Sergey";

            LastName = "Barskiy";

            Addresses = new List<CachableAddress>();

            Addresses.Add(new CachableAddress() { Street = "Main Street", City = "Atlanta" });

            Addresses.Add(new CachableAddress() { Street = "Second Street", City = "Lilburn" });

        }

    }

 

    public class CachableAddress

    {

        public string Street { get; set; }

        public string City { get; set; }

    }

 

I put the class into its own project and referenced this project from two separate WPF application projects.

First step in using caching is to configure cache object.  Here is how we can configure cache object using cache factory:

        private void SetupCache()

        {

            DataCacheServerEndpoint[] servers = new DataCacheServerEndpoint[1];

            servers[0] = new DataCacheServerEndpoint("Sergey-Laptop", 22233, "DistributedCacheService");

            _cacheFactory = new DataCacheFactory(servers, false, true);

            _defaultCache = _cacheFactory.GetCache("default");

        }

 

Now we are ready to add object to cache.  We will do this in steps.  First we check to see if an object is already in cache, and if so, we will remove it from cache.  Cache basically is using a string as the object key.  In addition to that you can also version objects, thus having multiple copies of the same object with the same key existing in cache at any given time.

            if (_defaultCache.Get("person") != null)

            {

                _defaultCache.Remove("person");

            }

            _defaultCache.Add("person", _person);

 

 

Now I am going to get the object from cache.  Just as simple as adding it:

_person = (CachablePerson)_defaultCache.Get("person");

 

Simple and easy.  I think Velocity is super powerful yet simple to use.  Event though it would be an abuse, but one could possibly use caching to communicate between different applications. 

You can download my sample solution here

Windows AppFabric and Velocity

I downloaded Windows AppFabric Beta 1 version this week.  You can find this download here. It took a few hours to install it.  I could surely tell I was dealing with beta 1 of version 1 of the product.  I finally installed it using new cluster option and XML configuration option.  I tried SQL Server configuration  option a few times, but it never installed without errors.  I think at the end I ran the install about a dozen times before it succeeded.

Anyway, three hours later or so I was done.  Next I tried to run a downloaded sample.   No matter what I tried, I could not get the sample to work.  It looked pretty obvious that I still need to configure something.  Finally after another 30 minutes I found an answer – I had to start the cache cluster.  To do so, I went to Programs –> Microsoft Distributed Cache –> Administration tool.  I was sort of surprised that this launched PowerShell window.  I guess we need to wait until release to get real nice configuration software with GUI.  In the mean time, I had to type “start-cachecluster”.  Once I ran that and saw that the server was started, I went back to run the samples.  They worked perfectly well this time.

Once I write my own sample, I will post source code on this blog.

Windows Azure Application

This is purely a bragging post :-)

I just deployed a test application to the cloud (Microsoft Azure): http://rolodex.cloudapp.net/

Here is the technology stack for it:

  1. Windows Azure
  2. SQL Azure
  3. CSLA 3.8.1
  4. Silverlight
  5. Entity Framework
  6. WCF
  7. Prism (Composite Application Guidance)
  8. Silverlight Toolkit

I promise to write a blog entry in the near future, the steps one has to follow through to create an Azure application.

Dynamically Styling Silverlight Applications

I spoke at GGMUG (Gwinnett Georgia Microsoft Users Group) on Thursday.  I was speaking about dynamically styling Silverlight applications using Implicit Style Manager from Silverlight Toolkit

Silverlight toolkit comes with about a dozen themes that anyone can use to style there applications.  In the example I am posting I use four of them,  A theme file is essentially a XAML file that contains styles for all native Silverlight controls as well as all Toolkit controls.  Implicit style manager allows developers to dynamically (or statically) load a theme and apply it to any FrameworkElement in the visual tree. 

There are only a few steps you need to do to implement this type of styling.

1.  Download and install Toolkit.

2.  Create new Silverlight application.

3.  Create new folder under applications (UserThemes in my example) and copy some or all themes from toolkit (C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Toolkit\Oct09\Themes is the default folder) into that folder.  Once you include all the themes into the project, set compile action to Content.

4.  Now write a few lines of code in key places to apply a chosen theme.  Here is what this code would look like:

        private void ApplyeTheme(string themeName)

        {

            Uri uri = new Uri(string.Concat("UserThemes/", themeName, ".xaml"), UriKind.Relative);

            ImplicitStyleManager.SetResourceDictionaryUri(this, uri);

            ImplicitStyleManager.SetApplyMode(this, ImplicitStylesApplyMode.OneTime);

            ImplicitStyleManager.Apply(this);

        }

5.  You can even allow application user to select a theme by creating for example a combo box loaded with available themes.

Implicit style manager does carry some overhead with it.  To minimize the overhead try to use apply mode of OneTime.  Ap0ply mode of Auto will watch for LayoutUpdated event and restyle attached element.  If you use this mode, you can apply this code to your shell (outer application frame), and any loaded control will be styled.  It sounds easy, but it will slow down your application.

As you can see, you cheaply and easily implement dynamic styling using free! software from Silverlight Toolkit.

You can download full example here.

Rocky Lhotka is Talking Oslo at ALEMUG

At out next Atlanta Leading Edge Microsoft Users Group Rocky Lhotka will be talking about Oslo.  Please visit ALEMUG.NET home page to register for this exciting event!

Here are the details of this event.

Microsoft code-name “Oslo” includes the ability to define your own domain specific  language (DSL), a metadata repository hosted in SQL Server and a graphical tool (“Quadrant”) to edit that metadata. One part of the Oslo vision is that you might define a DSL, build code in your language, compile that code into the repository and then create a runtime to dynamically execute that metadata. Taking this vision and combining it with the popular CSLA .NET framework, the result is MCsla. This is a prototype DSL grammar, repository schema and runtime that dynamically creates and executes CSLA .NET business objects with a WPF UI. The result is a fully functional application that you can create with a fraction of the code you’d need to write with traditional programming techniques. Learn how MCsla was created and how it works in this rapid-fire walk through the depths of the Olso technology.

Rockford Lhotka is the creator of the popular CSLA .NET development framework, and is the author of numerous books, including Expert C# 2008 Business Objects and Expert VB 2008 Business Objects. He is a Microsoft Regional Director, MVP and INETA speaker. He contributes to several major magazines and regularly presents at major conferences around the world. Rockford is the Principal Technology Evangelist for Magenic (www.magenic.com), a company focused on delivering business value through applied technology and one of the nation’s premiere Microsoft Gold Certified Partners. For more information go to www.lhotka.net.

Getting Started with SQL Azure

I setup an account with SQL Azure last week, and I would like to document each step I took in order. 

There is a lot of information on SQL Azure FAQ and Zack Owens’ blog.  I still ran into some issues though, and I wanted to provide detailed instruction on how to work through them.

Step 1 – Get SQL Azure token.  You need to Microsoft Azure site and scroll down the page to request tokens.

Step 2 – Wait for the email you will receive that will contain the token (invitation code) and instructions on how to activate it. Follow those step to setup an account.

Step 3 – Create new project in SQL Azure.  You will setup user ID and password as part of that process.

Step 4 – Create a database with a name you choose and setup firewall

image

 

image 

 

image

You can see your own IP address on this window above as well.  You can just copy that address and paste it into both IP ranges – low and high,

Step 5 – Start SSMS (SQL Server Management Studio).  Hit Cancel on initial login screen.

image

Step 6 – Click New Query button

image

Step 7 – Enter your server information, but do NOT click Connect

image

Step 8 – Click Options and enter your database name

image

Step 9 – Click “Connect”.  You should not get any errors and now you can see a query window.  You are ready to add tables.

Step 10 – Type in script to create database structure.  Important: not all standard SQL commands are supported.  If you are scripting an existing database, you will need to remove all file group references, such as “ON PRIMARY”. 

image

Step 11 – Create a standard .NET application.  You can get exact connection string on your SQL Azure management page:

image

You are done!

Find more information on SQL Azure FAQ and Zack Owens’ blog.

Entity Framework 4.0 CTP

I just installed CTP of entity framework 4.0 (2.0 technically).  I decided to test the most advertized feature – ability to have actual foreign keys (IDs) in addition to navigation properties.  The lack of this feature has been the biggest annoyance for me while working with Entity Framework for many months now.

Here is the model I created

image

As you can see Companies have Contacts, and each contact object now has CompanyID in addition to Company navigation property.  I had to select this option while generating the model from the database.  The checkbox for option to include foreign key values was available on one of the wizard screens.

Here is the code I wrote for testing:

 

            using (RolodexEntities context = new RolodexEntities())

            {

                CompanyContact newConact = new CompanyContact();

                newConact.CompanyId = 2;

                newConact.BaseSalary = 1;

                newConact.Birthday = DateTime.Today;

                newConact.FirstName = "Sergey";

                newConact.LastName = "Barskiy";

                newConact.RankId = 1;

                context.AddToCompanyContacts(newConact);

                context.SaveChanges();

            }

Hurray!  It worked!  New contact was added to the database and linked to Company with ID of 2 and Rank with ID of 1.

This feature to me is invaluable in n-Tier development when a developer has to replay the changes on the server after allowing the user to edit the data on the client.  Now, we can just transmit all properties of a Contact to the server, (probably with IsNew, IsUpdated, IsDeleted flags), set the foreign keys via IDs, then save.

Silverlight 3 – CollectionViewSource and Navigation

I am killing two birds with one stone in this post, covering both CollectionViewSource and Navigation framework in Silverlight 3.

To create new Silverlight application that uses Navigation framework, simply create new project in Visual Studio, and you will find Silverlight Navigation Application project template under Silverlight node.  Navigation framework in Silverlight three allows developers to create navigation structure that mimics the one of ASP.NET (or any web allocation for that matter).   In other words, this framework provide for URI driven navigation, using Uri routing feature similar to ASP.NET MVC framework.  Of course, this is really from end user perspective, not developer.  Obviously, Silverlight application cannot navigate from one to another XAML page using browser natively.  As a result, navigation framework utilizes browser bookmark feature in order to provide the user with Next/Previous navigation using actual browser buttons.  Routing engine enables the mapping between short Uri and actual XAML page that is supposed to handle the navigation event to this Uri.  Here is what this routing looks like:

            <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"

                             Source="/Home" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">

                <navigation:Frame.UriMapper>

                    <uriMapper:UriMapper>

                        <uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>

                        <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>

                        <uriMapper:UriMapping   

                           Uri="ProductDetail/{ProductId}"   

                           MappedUri="/Views/ProductDetail.xaml?ProductId={ProductId}"/>

                    </uriMapper:UriMapper>

                </navigation:Frame.UriMapper>

            </navigation:Frame>

Here is how we read this code.  The core part of navigation is Frame control.  It handles browser interaction and provide Uri mapping.  If we look at the mapper XAML, we will see that short Uri, such as “” (blank) maps to Home.Xaml.  Home.Xaml is not User Conrol, it inherits from Page control, another part of navigation framework.  Any XAML page that is supposed to handle navigation must inherit from Page.  The mapper supports tokenization as well, that is how {pageName} is mapped to /Views/{pageName}.xaml.  So, if we navigate to Uri “Home”, /Views/Home.xaml will be loaded into the frame. For example, we have HyperLinkButton as follows:

                    <HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}"

                                    NavigateUri="/About" TargetName="ContentFrame" Content="about"/>

In this case when user clicks on this button, he/she will be navigated to /Views/About.xaml that will be shown in Frame called ContentFrame.

Navigation framework also supports parameters, and incidentally it took me an hour to figure those out.  In the example above our ProductDetail mapping supports parameter called PrductId.  So, far pretty easy.  The hard part is to figure out how to set that Url.  In my case, I have a product object, and I am setting the Url in it to match my mapping.  Here is full source code for Product class and collection of products:

using System;

 

namespace SilverlightNavigationApp

{

    public class Product

    {

        public string ProductId { get; set; }

        public string ProductName { get; set; }

        public string ProductDescription { get; set; }

        public Uri Url { get; set; }

    }

}

using System;

using System.Collections.ObjectModel;

 

namespace SilverlightNavigationApp

{

    public class ProductList : ObservableCollection<Product>

    {

        public ProductList()

        {

            Add(new Product() { ProductId = "1", ProductName = "Bread", ProductDescription = "Wheat bread.", Url = new Uri("ProductDetail/1", UriKind.Relative) });

            Add(new Product() { ProductId = "2", ProductName = "Milk", ProductDescription = "Whole milk.", Url = new Uri("ProductDetail/2", UriKind.Relative) });

            Add(new Product() { ProductId = "3", ProductName = "Potatoes", ProductDescription = "Red potatoes.", Url = new Uri("ProductDetail/3", UriKind.Relative) });

            Add(new Product() { ProductId = "4", ProductName = "Water", ProductDescription = "Bottled water.", Url = new Uri("ProductDetail/4", UriKind.Relative) });

            Add(new Product() { ProductId = "5", ProductName = "Cake", ProductDescription = "Chocolate cake.", Url = new Uri("ProductDetail/5", UriKind.Relative) });

        }

    }

}

So far so good.  You can see how Url must be formatted to match product Id. I am showing product list inside a page using DataGrid.

<navigation:Page x:Class="SilverlightNavigationApp.Views.ProductList"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:local="clr-namespace:SilverlightNavigationApp"

   xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"

   xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

   >

    <UserControl.Resources>

 

        <CollectionViewSource Source="{StaticResource ProductList}" x:Key="ViewSource" Filter="MyFilter"/>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="*"/>

        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="Auto"/>

            <ColumnDefinition Width="*"/>

        </Grid.ColumnDefinitions>

        <TextBlock Text="Fitler:"/>

        <TextBox Grid.Column="1" TextChanged="TextBox_TextChanged" x:Name="FilterBox" Text=""/>

        <data:DataGrid

           ItemsSource="{Binding Source={StaticResource ViewSource}}"

           AutoGenerateColumns="False"

           Grid.Row="1"

           Grid.ColumnSpan="2">

            <data:DataGrid.Columns>

                <data:DataGridTextColumn Binding="{Binding ProductId}" Header="Product ID"/>

                <data:DataGridTextColumn Binding="{Binding ProductName}" Header="Product Name"/>

                <data:DataGridTextColumn Binding="{Binding ProductDescription}" Header="Description"/>

                <data:DataGridTemplateColumn>

                    <data:DataGridTemplateColumn.CellTemplate>

                        <DataTemplate>

                            <Button Content="Details" Tag="{Binding Url}" Click="Button_Click"/>

                        </DataTemplate>

                    </data:DataGridTemplateColumn.CellTemplate>

                </data:DataGridTemplateColumn>

            </data:DataGrid.Columns>

        </data:DataGrid>

    </Grid>

</navigation:Page>

You can see that I am setting the tag for the button to Url property of the Product object.  Here is how I am processing this information in click event:

        private void Button_Click(object sender, RoutedEventArgs e)

        {

            NavigationService.Navigate(((Button)sender).Tag as Uri);

        }

Here is what we can do with this in the Details page:

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)

        {

            string productId = this.NavigationContext.QueryString["ProductId"].ToString();

            SilverlightNavigationApp.ProductList list = (SilverlightNavigationApp.ProductList)App.Current.Resources["ProductList"];

            Product product = (from one in list

                               where one.ProductId == productId

                               select one).FirstOrDefault();

            this.DataContext = product;

        }

Alternatively, I can use propertied of HyperLinkButton to do the same if I do not need to use dynamic parameters.  Look above for About navigation.

Now, let’s talk about ColllectionViewSource.  It suports grouping, sorting and filtering.  In the example I will use filtering technique.  The filtering is pretty easy – we just subscribe to filter event, evaluate each object, and decide whether or not show it:

    <UserControl.Resources>

        <CollectionViewSource Source="{StaticResource ProductList}" x:Key="ViewSource" Filter="MyFilter"/>

    </UserControl.Resources>

        private void MyFilter(object sender, FilterEventArgs e)

        {

            Product product = e.Item as Product;

            if (FilterBox != null)

            {

                e.Accepted = product.ProductName.ToUpper().Contains(FilterBox.Text.ToUpper()) ||

                    product.ProductDescription.ToUpper().Contains(FilterBox.Text.ToUpper());

            }

            else

                e.Accepted = true;

        }

All that is left is to call refresh when we want to response to use actions:

        <TextBox Grid.Column="1" TextChanged="TextBox_TextChanged" x:Name="FilterBox" Text=""/>

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)

        {

            CollectionViewSource source = this.Resources["ViewSource"] as CollectionViewSource;

            source.View.Refresh();

        }

Pretty simple.  You can download full example here.

Silverlight 3.0 Behaviors – Part 2

Today I am going to explore Silverlight three behaviors a little more.  In this post I am going to look at different events that can trigger an action in a behavior.  Essentially, we can specify any event on a target element to invoke a behavior. 

Again, we are going to use TargetedTriggerAction base class. This time however we are going to enable this behavior to be able to be used on a larger suite of targets.  We are going to use UIElement as the target type: TargetedTriggerAction<UIElement>.  We are only going to override one method – InvokeAction.  Here is what the class looks like:

    public class MakeLargerSmallerAction : TargetedTriggerAction<UIElement>

    {

        protected override void Invoke(object parameter)

        {

            StoryBoardHelper.PlayControlAnimation(Target, Percent);

        }

Here are a couple of things I need to explain. 

  1. This behavior is going to perform one function – change dimensions (increase or decrease the size) of the target control base on an event.  We are going to add a property that would allow our behavior to specify the factor by which the target’s size needs to increase or decrease.
  2. We are going to use animations to perform this function.  We will build animations in code.
  3. We will invoke animations based on event specified in XAML.

Here is full source code for behavior class:

using System;

using System.Windows.Interactivity;

using System.Windows;

 

namespace Behaviors

{

    public class MakeLargerSmallerAction : TargetedTriggerAction<UIElement>

    {

        protected override void Invoke(object parameter)

        {

            StoryBoardHelper.PlayControlAnimation(Target, Percent);

        }

 

        public double Percent

        {

            get { return (double)GetValue(PercentProperty); }

            set { SetValue(PercentProperty, value); }

        }

 

        public static readonly DependencyProperty PercentProperty =

            DependencyProperty.Register("Percent", typeof(double), typeof(MakeLargerSmallerAction), new PropertyMetadata((double)1));

 

 

    }

}

Here is source code for animation controller:

using System;

using System.Windows;

using System.Windows.Media;

using System.Windows.Media.Animation;

 

namespace Behaviors

{

    public static class StoryBoardHelper

    {

        public static void PlayControlAnimation(UIElement controlToAnimate, double factor)

        {

            Storyboard story = new Storyboard();

 

            //stretch horizontally

            DoubleAnimationUsingKeyFrames scaleXAnimation = new DoubleAnimationUsingKeyFrames();

            scaleXAnimation.BeginTime = TimeSpan.FromMilliseconds(0);

            scaleXAnimation.KeyFrames.Add(CreateFrame(factor, 100));

            Storyboard.SetTarget(scaleXAnimation, controlToAnimate);

            Storyboard.SetTargetProperty(scaleXAnimation, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));

            story.Children.Add(scaleXAnimation);

 

            //stretch vertically

            DoubleAnimationUsingKeyFrames scaleYAnimation = new DoubleAnimationUsingKeyFrames();

            scaleYAnimation.BeginTime = TimeSpan.FromMilliseconds(0);

            scaleYAnimation.KeyFrames.Add(CreateFrame(factor, 100));

            Storyboard.SetTarget(scaleYAnimation, controlToAnimate);

            Storyboard.SetTargetProperty(scaleYAnimation, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));

            story.Children.Add(scaleYAnimation);

 

            if (!(controlToAnimate.RenderTransform is TransformGroup))

            {

                TransformGroup group = new TransformGroup();

                ScaleTransform transform = new ScaleTransform();

                transform.ScaleX = 1;

                transform.ScaleY = 1;

                group.Children.Add(transform);

                controlToAnimate.RenderTransformOrigin = new Point(0.5, 0.5);

                controlToAnimate.RenderTransform = group;

            }

            story.Begin();

 

 

        }

 

        private static SplineDoubleKeyFrame CreateFrame(double value, double duration)

        {

            SplineDoubleKeyFrame frame = new SplineDoubleKeyFrame();

            frame.Value = value;

            frame.KeyTime = TimeSpan.FromMilliseconds(duration);

            return frame;

        }

    }

}

Here is how we are setting up behaviors in XAML:

        <TextBox x:Name="FirstBox" TextWrapping="Wrap" Margin="20,0,0,7" d:LayoutOverrides="Height">

            <i:Interaction.Triggers>

                <i:EventTrigger>

                    <Behaviors:SelectOnFocusAction/>

                </i:EventTrigger>

                <i:EventTrigger EventName="GotFocus">

                    <Behaviors:MakeLargerSmallerAction Percent="1.2"/>

                </i:EventTrigger>

                <i:EventTrigger EventName="LostFocus">

                    <Behaviors:MakeLargerSmallerAction Percent="1"/>

                </i:EventTrigger>

            </i:Interaction.Triggers>

        </TextBox>

In the XAML above we are setting up three different behaviors.  First one I covered in previous post.  The second trigger increases the size of the control by factor of 1.2 – 20 %.  This action is executed when GotFocus event fires.  The last trigger changes the control’s size back to original size.

You can download full sample project here.

Unable to debug Silverlight applications

I have run into this issue numerous times, but from time to time I keep forgetting what causes this issue.

The symptom is that your breakpoints inside Silverlight application cannot be hit, and the information message states that “No symbols have been loaded for this document.”  What is usually strange that I was able to debug just a little while ago.

The most common cause is that Silverlight debugging is not turned on on web site project that hosts Silverlight application.  However, I have not run into this issue.  My number one problem is that ClientBin folder stops being updated.  This can be caused by the fact that somehow the folder is checked into source control and compiler cannot overwrite the XAP file any longer.  Or, file is being held by OS, maybe because Visual Studio crashed at some point before.  To troubleshoot, just check your XAP from ClientBin folder and check source controls.

Dynamically setting initialization parameters in Silverlight application

One of the properties on object tag for Silverlight control in initParams or initialization parameters:

 

 <object name="objSilverlight" data="data:application/x-silverlight-2," type="application/x-silverlight-2"

            width="100%" height="100%">

            <param name="source" value="ClientBin/SilverlightInitParams.xap" />

            <param name="onError" value="onSilverlightError" />

            <param name="background" value="white" />

            <param name="minRuntimeVersion" value="3.0.40624.0" />

            <param name="autoUpgrade" value="true" />

            <param name="initParams" value="key=value,key1=value1"/>

            <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration: none">

                <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight"

                    style="border-style: none" />

            </a>

        </object>

We can use this parameter to inform our Silverlight application about a specific piece of data it may need.  To access this data inside Silverlight application, you would need to use arguments from application startup event:

private void Application_Startup(object sender, StartupEventArgs e)

        {

            MainPage page = new MainPage();

            var paramList = e.InitParams.ToList();

Our initial parameters collection is exposed as a dictionary off Startup Event Arguments.

The next step it to dynamically set the parameter.  The problem is that the object tag / Silverlight application creation occurs on the client side, which has no access to server data.  We are going to play a trick here and modify our aspx page to delegate creation of actual parameters string to the page itself:

<param name="initParams" value="<%=GetInitParameter() %>" />

The next step is to write a method in our page that returns a string in format key=value.  Here is entire code behind for our aspx page:

    public partial class _Default : System.Web.UI.Page

    {

        private string _params = string.Empty;

 

        protected void Page_Load(object sender, EventArgs e)

        {

            // put a fake variable into session.  Ordinarily, we are just getting

            // data from somewhere on the server. 

            // could even be a database call if necessary

            Session["User"] = "Sergey Barskiy";

 

            //now set a variable

            _params = string.Concat("User=", Session["User"].ToString());

        }

 

        public string GetInitParameter()

        {

            return _params;

        }

    }

Here is what we do inside our Startup routine in Silverlight application:

 

        private void Application_Startup(object sender, StartupEventArgs e)

        {

            MainPage page = new MainPage();

            var paramList = e.InitParams.ToList();

            page.Key.Text = String.Format("{0} = ", paramList.First().Key);

            page.Value.Text = paramList.First().Value;

 

            RootVisual = page;

 

        }

You can download this sample application here.

Silverlight 3.0 Behaviors – Part 1

In this post I will start exploring behaviors in Silverlight 3.0.  This topic is very large, and it will take me a few posts to cover at least key aspects of behaviors.

A little background on the subject.  Silverlight, unlike WPF does not natively support triggers that would allow the developer to change UI based on criteria or data.  In Silverlight 3.0 we now have a facility to support similar behavior.  One key usage scenario for behaviors is to allow a designer to support UI changes based on user actions without writing any code.

To extend an existing behavior base class we need to add a reference to System.Windows.Interactivity DLL.  We will start with a simple behavior.  By default Silverlight Textbox does not select all the text when it gets focus.  This however us a desirable behavior from a user perspective in many scenarios.  So, for our first excursion into Silverlight behaviors we will write “Select All Text On Focus in Textbox” behavior.

We will start by extending an existing class in SilverlightTargetedTriggerAction<C>.  In our case we are supplying generic type for our behavior – Textbox - TargetedTriggerAction<TextBox>. 

We are specifying Textbox as the target type for our behavior.  Typically, we would specify an action and an event that would invoke the action on the behavior.  In our case we however want to make sure that they only event that invokes the behavior is GotFocus event.  So, we are leaving our Invoke method blank.  Here is the final version of the class:

using System;

using System.Windows.Controls;

using System.Windows.Interactivity;

 

namespace Behaviors

{

    public class SelectOnFocusAction : TargetedTriggerAction<TextBox>

    {

        protected override void OnAttached()

        {

            base.OnAttached();

            Target.GotFocus += Target_GotFocus;

        }

 

        void Target_GotFocus(object sender, System.Windows.RoutedEventArgs e)

        {

            Target.SelectAll();

        }

        protected override void OnDetaching()

        {

            base.OnDetaching();

            Target.GotFocus -= Target_GotFocus;

        }

 

        protected override void Invoke(object parameter)

        {

            //do nothing

            // we are handling specific event we are interested in

            // by attaching events to the target text

        }

       

    }

}

 

You can download the sample project with this behavior and text page here.

C# 4.0 (.NET 4.0) Features

As part of our first ALEMUG meeting I did a presentation on some of the new features in C# 4.0.  Here is what I talked about.

First topic was on optional and named parameters in C#.  Here is how you would define a function with optional parameters:

public static int AddTwoOrThreeOrFourNumbers(int numberOne = 0, int numberTwo = 0, int numberThree = 0, int numberFour = 0)

{

    int returnValue = numberOne + numberTwo + numberThree + numberFour;

    return returnValue;

}

All you need to do to define optional parameters is to provide a default value for each one. Here is how you could call this function by providing values only for some parameters:

ClassWithOptionalParameters.AddTwoOrThreeOrFourNumbers(1, 2)

As you see, I only supplied two out of three parameters.  All the magic is preformed by the compiler.  If you look at disassembled code, you will find that call to the function actually has all three parameters defined, just the last one is zero.

Another related feature is named parameters.  You can actually specify the name and the value for each parameters explicitly and out of order even:

ClassWithOptionalParameters.AddTwoOrThreeOrFourNumbers(numberOne: 1, numberFour: 4)

 

There are a few great uses for named / optional parameters.  One is COM Interop, specifically Office Interop.  Many functions in the Office take a number of optional parameter.  Right now you have to specify all of them.  With C# 4.0 you can specify just the ones you need.  Here is an example for SavedAs:

var format = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatDocument97;

Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();

var doc = word.Documents.Add();

doc.SaveAs(FileName: fileNameSaved, FileFormat: format);

In general, there are many features in C# to make Office development easier.  One of them (pointed out by Jim Wooly)  is No PIA – No Primary Interop Assembly distribution. To use this feature just go to properties of office interop assembly in the references window and set Embed Interop Types to True.  If you do, you do not have to distribute Interop assembly! 

Another features I talked about is dynamics.  Here is you declare a dynamic variable:

dynamic person = ExpandoClass.GetExpando();

Looks very similar to var, doesn’t it?  There is a big difference though between vars and dynamics.  The key difference is the resolution time.  Vars are resolved at compile time, and they are actually strongly typed in the running program.  Dynamics on the other hand are resolved at run time.  As a result, you can compile pretty much any code that refers to dynamics.  For example, you can type

dynamic thing = GetSomeDynamicObject();

thing.SomeProperty = 1;

SomeProperty actually does not exist anywhere in the source code, it is called dynamically at run time and it will succeed as long as whatever object is returned by GetSomeDynamicObject function has this property.  Very powerful feature when it comes to interacting with objects unknown at compile time.  You can use it to interact with dynamic languages such Python or COM objects or even other .NET objects.  Here is some code I came up with (not that I would write something like this, but it demonstrate the power of the feature) – universal sorter that can sort any collection:

    public static class DynamicDemo

    {

        public static IEnumerable<dynamic> GetSortedData(IEnumerable<dynamic> initialCollection, Func<dynamic, dynamic> sortExpression)

        {

            dynamic retVal = (from one in initialCollection

                              orderby sortExpression(one)

                              select one);

            return retVal;

        }

Dynamics is a very powerful features, but can be easily abused.  Also, anything can be dynamic, not just objects.  You can also have dynamic properties and methods and their parameters.

Another related feature is ExpandoObject.  This is a dynamic object that can be “expanded” at run time to contain custom properties and values:

dynamic expando = new System.Dynamic.ExpandoObject();

expando.Name = "Sergey Barskiy";

expando.Age = 18;

Seems pretty weird – I actually define the object at run time.

You can download sample solution (requires VS 2010) here.

ALEMUG.net meeting

Atlanta Leading Edge Microsoft Users Group is meeting tomorrow.  Our topic will be new features in C# 4.0 and .NET Framework 4.0.  Some of the topics are contra-variance and co-variance, dynamic types, office interop, named and optional parameters, code contracts.

Please join us tomorrow for an exciting meeting.  See the website for directions and times – www.alemug.net.

See you tomorrow.

SQL Saturday #25

I spoke yesterday at SQL Saturday event in Gainesville, GA.  My topic was CLR Integration in SQL Server. 

CLR stands for Common Language Runtime or .NET Framework.  This SQL Server 2005 or higher feature allows developers to write .NET assemblies and deploy them in SQL Sever.  You can implement scalar and table-values functions, stored procedures, triggers, user defined types and aggregates.

In my talk I spoke of features that I worked or had a need for.  Those included interacting with OS, such as file access or registry access.  I also talked about implementing fuzzy matching logic, creating custom bitmaps and utilizing them in SSRS reports.

You can download the sides and sample project here.

Thank you.

Silverlight 3.0 – Perspective 3D

I am continuing covering new features in Silverlight 3.0.  The subject of this post is Silverlight 3.0.

Perspective 3D is new type of transforms available in Silverlight 3.0.  It allows developers to create a 3D projection of a two-dimensional object.  A key power of this new feature is the fact that any UI element in Silverlight can be used as a target for this feature.  This means you can rotate a control in thee dimensional space around any axis.  In my example I am using this Plane Projection to rotate a calendar:

image

I am rotating the calendar control around X axis with center of rotation at x=0, y=0.5.  These values are set as relative values with 0.5 being the middle of the plane.  This allows us to create a rotation similar to an actual wall calendar’s page  turned by a person.  You can rotate around multiple axis in multiple planes, create nice visual effects.  Pretty cool.

 

You can download the sample project here.

Assembly caching in Silverlight 3.0

I am continuing discussing new features on Silverlight 3.0.  Current topic is assembly caching. 

In Silverlight 2.0 all assemblies that your application needed would have to be included in your XAP file(s).  In Silverlight 3 you can force browser to cache one or more assemblies that your application needs.  In case of caching your can tell Silverlight runtime to pull these cached assemblies from a predefined location.  This location can be the same folder as your Silverlight XAP file or anywhere else on the internet.  To cache assemblies, you can turn on caching option in project properties:

image

What you will notice if you do that, that Microsoft assemblies such as System.Windows.Controls.Data (contains DataGrid) will not be included in your XAP file.  Instead if you look at the manifest file inside your XAP file, you will notice that this DLL is pulled at runtime from the same folder as your application.  The information about this is incluided in assembly manafiest in your main XAP file.  Here what it would look like:

<Deployment
xmlns=http://schemas.microsoft.com/client/2007/deployment
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
EntryPointAssembly="CompanySLApp"
EntryPointType="CompanySLApp.App"
RuntimeVersion="3.0.40624.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="CompanySLApp" Source="CompanySLApp.dll" />
  </Deployment.Parts>
  <Deployment.ExternalParts>
    <ExtensionPart Source="System.Windows.Controls.Data.zip" />
    <ExtensionPart Source="UtilityFunctions.zip" />
    <ExtensionPart Source="System.Windows.Controls.Data.Input.zip" />
    <ExtensionPart Source="System.Windows.Data.zip" />
    <ExtensionPart Source="System.ComponentModel.DataAnnotations.zip" />
  </Deployment.ExternalParts>
</Deployment>

If you try to do the same with your assembly (for example you have a common assembly shared between two Silverlight applications), your will notice that it is still included.  The reason for that is that compiler is looking for XXX..extmap.xml where XXX is your assembly names without DLL extension.  So, all your need to do is create one.  You can look for an example in C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Libraries\Client folder for any extmap files for Microsoft assemblies.  You can use a utility to generate your own too.  (http://www.devcorner.info/Sources/Emm.zip).  Once you generate extmap file for your assembly, make sure it is located in the same folder as the assembly dll.  Once you rebuild your solution, you will find XXX.zip file in ClientBin folder that contains your XXX.dll assembly file.  Now, at runtime browser will cache that assembly for you, saving download time during application start up time.  Of course, this depends on how caching is setup for virtual directory that contains your Silverlight application.  You can also pass addition parameters to emm.exe utility and force it to setup download URL for your included assembly that point to an absolute URL somewhere else.  Using this feature for example, you can host assemblies that you can include in many applications on a separate server with a predefined URL.

Please feel free to ask questions about this feature.  You can upload sample application that uses assembly caching here.

Silverlight And N-Tier Data Access using Entity Framework

As I mentioned before I talked at GGMUG last Thursday.  I talked about Entity Framework in general and specifically in N-Tier applications, such as Silverlight applications.  I think I got a few folks excited about using Entity Framework.  The key thing to remember when using EF in N-Tier applications is that EF keeps track of changes in the context object.  Unfortunately, this object does not survive the trips between client and the server.  As a result, my recommendation is to use EF in conjunction with a business layer framework, such as CSLA. You can download slides and sample project here.  Please feel free to post comments or questions.

ElementName Binding in Silverlight 3

As I mentioned before, I will be working on a series of posts on new features in Silverlight 30.  This post is all about ElementName binding.

Probably my favorite feature in Silverlight 3 that affects developers writing business applications is addition of ElementName property to Binding object.  This features existed in WPF since version 1, but was missing from Silverlight 2.0.  The basic strategy behind the feature is the ability to bind a property on one UI element to a property on another UI element.  Here is a very common scenario in a business application that this features makes much simpler to implement.  Say, you have two co-dependent combo boxes.  For example, you have a combo box  with a listing of states, and once a state is selected, second combo box is populated with a list of cities for that state.

The basic syntax for ElementName binding is as follows:

ItemsSource="{Binding ElementName=ParentCombo, Path=…

In my case, I am going to illustrate the feature by having a list of dozens, each with a list of numbers that belong to that dozen.  Here are my classes:

    public class Each

    {

        public string Name { get; set; }

        public int Id { get; set; }

 

        public static Each GetEach(int id)

        {

            Each newEach = new Each();

            newEach.Id = id;

            newEach.Name = id.ToString();

            return newEach;

        }

    }

    public class Eaches : List<Each>

    {

 

    }

    public class Dozen

    {

        public string Name { get; set; }

        public int Id { get; set; }

        public Eaches Items {get;set;}

 

        public static Dozen GetDozen(int id)

        {

            Dozen newDozen = new Dozen();

            newDozen.Id = id;

            newDozen.Name = id.ToString();

            newDozen.Items = new Eaches();

            for (int i = 1; i <= 12; i++)

            {

                newDozen.Items.Add(Each.GetEach(((id – 1) * 12) + i));

            }

            return newDozen;

        }

    }

    public class Dozens : List<Dozen>

    {

        public Dozens()

        {

            for (int i = 1; i < 10; i++)

            {

                Add(Dozen.GetDozen(i));

            }

        }

    }

Now, I am going to add my Dozens class as a resource to a xaml page:

<UserControl x:Class="SilverlightApplication7.MainPage"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

   xmlns:local="clr-namespace:SilverlightApplication7"

   mc:Ignorable="d"

   d:DesignWidth="640"

   d:DesignHeight="480"

   >

    <UserControl.Resources>

        <local:Dozens x:Key="data"/>

    </UserControl.Resources>

The last step is to tie two combo boxes together:

  <Grid x:Name="LayoutRoot">

        <Grid.RowDefinitions>

            <RowDefinition Height="Auto"/>

            <RowDefinition Height="30"/>

            <RowDefinition Height="Auto"/>

        </Grid.RowDefinitions>

        <ComboBox x:Name="ParentCombo" Width="300" HorizontalAlignment="Left" ItemsSource="{StaticResource data}" DisplayMemberPath="Name"/>

        <ComboBox x:Name="ChildCombo" Grid.Row="2" Width="300" HorizontalAlignment="Left" ItemsSource="{Binding ElementName=ParentCombo, Path=SelectedItem.Items}" DisplayMemberPath="Name"/>

    </Grid>

Here is the summary of what we did.  We used Dozens class (the list of Dozen objects) that was populated when its constructor was invoked as part of resources collection initialization.  Then we used this object to populate ParentCombo with data.  We set DisplayMemberPath to show a desired property in combo box.  Then we used SelectedItem property from ParentCombo to be the source of items in ChildCombo.  As the user selects an item in ParentCombo, we can see that list of items inside ChildCombo is changing without any code-behind.  We also use dotted syntax (Path=SelectedItem.Items), so we can tie the eaches collection in dozens object to be the item source for another UI element.  In our case SelectedItem of ParentCombo is actually an instance of a Dozen object.  Items property of it gives us eaches collection.  Simple, yet very powerful feature.

You can download this sample project here.

I will be talking at GGMUG on Thursday, September 10th

I will be presenting at the next Gwinnett Georgia Microsoft Users Group this coming Thursday.  The topic of my presentation will be Entity Framework in general and its applications to Silverlight development.  I will be posting the zip file with slides and sample application immediately after the presentation.

I hope to see you there!

Atlanta Silverlight Fire Starter Event

Atlanta Silverlight Fire Starter event yesterday was awesome!  There were over 100 people attending.  The vast majority stayed there for the entire length of the event that lasted from 8am until 6pm.  All presenters did a great job.  All attendees were great.  They actively participated in all discussions, asking many questions.  Many thanks to all the event sponsors who helped make Fire Starter possible,  The event was truly a communal effort pulled off by many people excited about the technology and willing to share their knowledge and experience.  Please see Silverlight Atlanta site for more details about the event and its sponsors.

I posted my presentation about Deploying Silverlight Applications that I presented at the Fire Starter here.  The zip file contains sample project, database backup and PowerPoint presentation.

I was also going to chat for a couple of minutes about reporting in Silverlight and localization in Silverlight, however we of ran out of time by the end of the day.  I pushed an example in localization into the zip file above.  Just look at how title is setup on the main screen.  If you are interested in reporting in Silverlight, just find the blog entries on this topic on this blog.  There is also a sample project here on that showcases reporting in Silverlight.

I’d like to thank again to all involved in Fire Starter event, presenters, attendees and sponsors alike.

Bug Fix Release for SilverlightDatabase project

I just posted a new release for SilverlightDatabase project on CodePlex : http://silverdb.codeplex.com/

There was an issue with the latest release – you could potentially get an error when adding data to a table previously saved.  I posted a bug fix release for this that also includes unit test to verify that the issue is resolved.

Please download this release if you are using this project.

Thank you.

Webinar (Reporting in Silverlight) download

Recording of the webinar I presented is now up on Magenic web site.  Here is the address: http://www.magenic.com/Default.aspx?tabid=635

Since I am not sure if the sample project is available, I decided to post the zip file with the sample project here.

Please let me know if you have any questions. 

More on CodePlex project

I could not have been more pumped about my Silverlight database project (See my post from a week ago for details).  I searched CodePlex for “Silverlight”, and now my project is number 20 on the list sorted by relevance out of total  622 projects.  It is also listed on Silverlight MSDN main page today: http://msdn.microsoft.com/en-us/silverlight/default.aspx.  It got 68 downloads and 311 visits in just four days this week.  Awesome!

I just posted another update to this project on CodePlex.  Silverlight Database now supports encryption and compression.

A small localization gripe for Silverlight

I just installed Silverlight 3 last Friday.  One feature that I was hoping to see fixed was localization in Silverlight.  Ideally, I like to bind localized data, such as labels in XAML.  For example:

<UserControl.Resources>

<resources:ModuleResources x:Key="LanguageResource" />

then,

<TextBlock HorizontalAlignment="Center" Margin="7,0,7,0" VerticalAlignment="Center" Text="{Binding Source={StaticResource LanguageResource}, Path=SomePropertyName}"></TextBlock>

This works great, but there is one issue.  Even though I mark the resource as public, any time I add a new value or edit and existing value, ModuleResources .Designer.cs gets re-written, and its constructor is marked as internal, not public.  If I run the app, I get the dreaded unknown type exception.  At that point I have to manually edit designer file and mark constructor as public.  Not a major problem, but I would like not to have to do this.

CodePlex project

I just uploaded and published new CodePlex project I have been working on.  It is an Isolated Storage based database for Silverlight.  It supports multiple strongly typed tables, basic Linq based operations, addition and deletion of ranges of items, deletion of items based on condition.  You can also directly bind data to UI in Silverlight because base table inherits from ObservableCollection.  I am planning to put encryption and compression support into it next along with lazy loading of table.  Currently all tables are loaded into memory when database is opened.

Please take a look at http://silverdb.codeplex.com/

I would very much appreciate comments and feature requests related to this project.

Thanks in advance for the feedback.

Silverlight 3 Features

I am planning to write some posts on new features in Silverlight 3.0.

I decided to start with the easiest one – out of browser support.  Start by creating new Silverlight application in Visual Studio.  Once it is created, go to properties of the Silverlight application project.  You will see this window:

image

Check “Enable running application out of browser”, then click on Out-of-Browser Settings button.  You will see this screen.

image

Once you fill in all the settings, you are ready to go.  All settings from this screen are stored in XML file called OutOfBrowserSettings.xml.  The actual fact that a particular application is enabled for out-of-browser support is stored in .csproj file.

Once you run the application, if you right-click on the application, you will see context menu with additional option – install on desktop.  If application is already installed, the option changes to remove application.

The installed application can be now run from the computer from the shortcut.  When you run the app from the shortcut, it is not going run in the browser, instead it is run in sllauncher.exe, a special program designed to host Silverlight application.  At that point, you do not have access to browser based functionality.  So, before you reach to HtmlPage.Window, check to see if application is running in browser.  You can do this by checking App.Current.IsRunningOutOfBrowser property.

Webinar on reporting in Silverlight

I am presenting a webinar on July 28th on reporting in Silverlight.  This webinar is hosted by my employer, Magenic Technologies.  If you would like to register and watch this event, please follow this link: http://guest.cvent.com/EVENTS/Info/Invitation.aspx?e=6ca01a01-e2bd-4a77-a057-a63ab2208e81

There should be some tome allocated for questions and answers as well.

Thank you.

Entity Framework and multiple relationships between two tables

Here is a scenario – I have two tables – Users and Phones.  Users table has two columns that relate to Phones table – PrimaryPhone and SecondaryPhone.  If you build an EF model with these two tables, you will end up with Users entity with two navigation properties that relate to Phones entity – Phones and Phones1.  Yes, I hope this excellent :-( naming convention will be fixed in EF 2.0.  Our goal – retrieve the data for both phones with each user.  If you do the following:

var query = (from oneUser in Users.Include(“Phones”)

you will end up with only secondary (or primary) navigation property in Users object populated.  So, either Users.Phones or Users.Phones1 will have data, the other one will be null.  Important thing to realize when working with Entity Framework is that “.Includes”  statement works off navigation property names, not table names.  So, if you would like to populate both primary and secondary phone, you need to use the following query:

var query = (from oneUser in Users.Include(“Phones”).Include(“Phones1”)

Using Entity Framework as Data Access Layer in n-Tier applications

I have been using Entity framework as DAL for a CSLA for Silverlight based application.  I have player a role in uncovering a number of issues that make it very hard to use in these circumstances.  Here is my (surely incomplete) list.

1. Foreign keys handling.  The actual IDs that are used as foreign keys are not built as properties when you generate a model from a database.  Instead you get navigation properties.  For example, you have User and UserTypes table.  Users table has UserTypeID in it.  When you build a mode for this, you will have UserTypes property in Users entity, but not access to UserTypeID.  As a result, when you are rehydrating a users object in n-Tier environment, you have to have an instance of UserTypes entity to attach a user to.  Your options are to retrieve it from database (inefficient) or write a helper class that creates one on the fly.  To do so, you create an instance of UserTypes entity, then set entity key on it, then attach it to context.  To do all this, you will need to know ID in advance.  You can do this by using UserTypesReference property in Users entity – it will contain UserTypesID when you retrieve an instance of Users from DB.  You can store it in a property of the user object (CSLA for example) that you will use in UI.

2.  Another foreign key annoyance is an instance when you have multiple columns from one table relating to another table.  For example, Users table has columns PrimaryType and SecondaryType, both relating to UseTypes table.  As a result you will get navigation properties UserTypes1 and UserTypes2 in Users entity.  This is pretty much useless because as you write code against that, you will need to constantly have your model open to figure out what ID you need to use.  On top of that, if you use .Include(“UserTypes”) syntax to get the user with both primary and secondary columns, only one of the UserTypes properties will be populated with an instance of UserTypes if you have different IDs in property and secondary columns.  What do you do then?  Your only option is to use UserTypes1(2)Reference property to either get an ID or retrieve an instance of UserTypes table

3.  Third foreign key issue is concurrency handling.  Typically, for all properties you can indicate if a column is to participate in concurrency handling.  For some reason, you cannot do the same for navigation properties – they always participate in concurrency handling if they are changing.  As a result, you have to always keep track of old and new value for each navigation property,  You would set its old value before attaching it to the context, then set it to the new value.  If you capture the SQL query that is sent to the DB when the values are not the same, you will find navigation properties are part of the where clause / concurrency checking.  Sad but true.

4.  Re-using context for Oracle and SQL server (or any multiple databases).  Currently Microsoft ships entity framework only with SQL Server provider.  So, you are stuck buying some third party Oracle provider and hope that the model it generates will be the same as SQL server model, so that you only need to change connection string when switching databases.  There is a promise we might get there one day, but today is not that day.

Status Update

I am very tired, but Silverlight application our team has been working on for 6+ months is now officially live!  We saw that someone used it over the weekend!

More reflections on the project are to come in the next few weeks.

SQL Saturday Presentation

My talk at SQL Saturday just ended. My topic was CLR integration – Integ