Amazon.com Widgets
Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 2: Rich Data Query

Continuing in our discussion of Silverlight 3 and  the brand new update to .NET RIA Services and the update the example from my Mix09 talk “building business applications with Silverlight 3”.

You can watch the original  video of the full session 

The demo requires (all 100% free and always free):

  1. VS2008 SP1 (Which includes Sql Express 2008)
  2. Silverlight 3 RTM
  3. .NET RIA Services July '09 Preview

Also, download the full demo files and check out the running application.

Today, we will talk about Rich Data Query. 

 

Rich Data Query

Next up, let’s talk about data query.  Nearly every business application deals with data.   Let’s look at how to do this with .NET RIA Services.   We will start out in the web project.   For this example I will use an Entity Framework data model, but RIA Services works great with any form of data from plain olld CLR objects to an xml file, to web services to Linq to Sql.   For starters, let’s build an Entity Framework model for our data.   For this walk through, we will start simply…

image

I updated the pluralization of the entity name

Now, how are we going to access this data from the SL client?  Well, traditionally many business applications have started out as 2-tier apps. That has a number of problems around scaling and flexibility… and more to the point it just doesn’t work with the Silverlight\web client architecture.   

image

So developers are thrust into the n-tier world.  .NET RIA Services make it very easy to create scalable, flexible n-tier services that builds on WCF and ADO.NET Data Services. 

image

These .NET RIA Services model your UI-tier application logic and encapsulate your access to varies data sources from traditional relational data to POCO (plain old CLR objects) to cloud services such as Azure, S3, etc via REST, etc.  One of the great thing about this is that you can move from an on premises Sql Server to an Azure hosted data services without having to change any of your UI logic. 

Let’s look at how easy it is to create these .NET RIA Services. 

Right click on the server project and select the new Domain Service class

image_thumb[26]

In the wizard, select your data source.  Notice here we could have chosen to use a Linq2Sql class, a POCO class, etc, etc. 

image_thumb[28]

In the SuperEmployeeDomainService.cs class we have stubs for all the CRUD method for accessing your data.   You of course should go in and customize these for your domain.  For the next few steps we are going to use GetSuperEmployees(), so I have customized it a bit. 

public IQueryable<SuperEmployee> GetSuperEmployees()
{
    return this.Context.SuperEmployeeSet
               .Where(emp=>emp.Issues>100)
               .OrderBy(emp=>emp.EmployeeID);
}

Now, let’s switch the client side.  Be sure to build the solution so you can access it from the client directly.  These project are linked because we selected the “ASP.NET enable” in the new project wizard. 

Drag the DataGrid off the toolbox… notice this works with any control.. 

image_thumb[29]

In HomePage.Xaml add

<data:DataGrid x:Name="dataGrid1" Height="500"></data:DataGrid> 

And in the code behind add MyApp.Web… notice this is interesting as MyApp.Web is defined on the server…  you can now access the client proxy for the server DomainServices locally

image

   1: var context = new SuperEmployeeDomainContext();
   2: dataGrid1.ItemsSource = context.SuperEmployees;
   3: context.Load(context.GetSuperEmployeesQuery());

In line 1, we create our SuperEmployeesDomainContext.. this is the client side of the SuperEmployeesDomainService.  Notice the naming convention here…

In line 2, we are databinding the grid to the SuperEmployees.. then in line 3 we are loading the SuperEmployees, that class the GetSuperEmployees() method we defined on the server.  Notice this is all async of course, but we didn’t have to deal with the complexities of the async world. 

image_thumb[30]

The result!  We get all our entries back, but in the web world,don’t we want to do paging and server side sorting and filtering?  Let’s look at how to do that.

First, remove the code we just added to codebehind.

Then, to replace that, let’s add a DomainDataSource. You can just drag it in from the toolbox:

image_thumb[31]

Then edit it slightly to get:

   1: <riaControls:DomainDataSource x:Name="dds" 
   2:         AutoLoad="True"
   3:         QueryName="GetSuperEmployeesQuery"
   4:         LoadSize="20">
   5:     <riaControls:DomainDataSource.DomainContext>
   6:         <App:SuperEmployeeDomainContext/>
   7:     </riaControls:DomainDataSource.DomainContext>
   8: </riaControls:DomainDataSource>

Notice in line 3, we are calling that GetSuperEmployeesQuery method from the DomainContext specified in line 6.  

In line 4, notice we are setting the LoadSize to 20.. that means we are going to download data in batches of 20 at a time.

Now, let’s bind it to a the DataGrid and show a little progress indicator (that you can get in the sample).. 

   1: <activity:Activity IsActive="{Binding IsBusy, ElementName=dds}"
   2:                    VerticalAlignment="Top" 
   3:                    HorizontalAlignment="Left" 
   4:                    Width="900" Margin="10,5,10,0">
   5:     <StackPanel>
   6:         <data:DataGrid x:Name="dataGrid1" Height="300" Width="900"
   7:                        ItemsSource="{Binding Data, ElementName=dds}">
   8:          </data:DataGrid>
   9:          <data:DataPager PageSize="10" Width="900"
  10:                          HorizontalAlignment="Left"
  11:                          Source="{Binding Data, ElementName=dds}" 
  12:                          Margin="0,0.2,0,0" />
  13:      </StackPanel>
  14: </activity:Activity>

In line 6, there is a datagrid, that is bound  to the DDS.Data property (in line 7).  Then we add a DataPager in line 9, that is bound to the same datasource.  this gives us the paging UI.  Notice in line 9 we are setting the display to 10 records at a time.  Finally we wrap the whole thing in an ActivityControl to show progress.

The cool thing is that the ActivityControl, the DataGrid and the DataPager can all be used with any datasource such as data from WCF service, REST service, etc. 

Hit F5, and you see.. 

image_thumb[35]

Notice we are loading 20 records at a time, but showing only 10.  So advancing one page is client only, but advancing again we get back to the server and load the next 20.  Notice this all works well with sorting as well.   And the cool thing is where is the code to handle all of this?  Did i write in on the server or the client?  neither.  Just with the magic of linq, things compose nicely and it i just falls out. 

I can early add grouping..

<riaControls:DomainDataSource.GroupDescriptors>
    <datagroup:GroupDescriptor PropertyPath="Publishers" />
</riaControls:DomainDataSource.GroupDescriptors>

image_thumb[37]

Let’s add filtering… First add a label and a textbox..

<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
    <TextBlock Text="Origin: "></TextBlock>
    <TextBox x:Name="originFilterBox" Width="75" Height="20"></TextBox>
</StackPanel>

and then these filter box to our DomainDataSource….

<riaControls:DomainDataSource.FilterDescriptors>
    <datagroup:FilterDescriptorCollection>
        <datagroup:FilterDescriptor PropertyPath="Origin"
                           Operator="StartsWith">
            <datagroup:ControlParameter PropertyName="Text" 
                           RefreshEventName="TextChanged"
                           ControlName="originFilterBox">
            </datagroup:ControlParameter>
        </datagroup:FilterDescriptor>
    </datagroup:FilterDescriptorCollection>
</riaControls:DomainDataSource.FilterDescriptors>

When we hit F5, we get a filter box, and as we type in it we do a server side filtering of the results. 

image_thumb[40]

Now, suppose we wanted to make that a autocomplete box rather an a simple text box.   The first thing we’d have to do is get all the options.  Notice we have to get those from the server (the client might not have them all because we are doing paging, etc).  To do this we add a method to our DomainService. 

public class Origin
{
    public Origin() { }
    [Key]
    public string Name { get; set; }
    public int Count { get; set; }
}

and the method that returns the Origins…

public IQueryable<Origin> GetOrigins()
{
    var q = (from emp in Context.SuperEmployeeSet
             select emp.Origin).Distinct()
            .Select(name => new Origin
            {
                Name = name,
                Count = Context.SuperEmployeeSet.Count
                    (emp => emp.Origin.Trim() == name.Trim())
            });
    q = q.Where(emp => emp.Name != null);
    return q;
}

Now we need to add the autocomplete control from the Silverlight 3 SDK.  Replace the textbox with this:

<input:AutoCompleteBox  x:Name="originFilterBox" Width="75" Height="30"
                        ValueMemberBinding="{Binding Name}" 
                        ItemTemplate="{StaticResource OriginsDataTemplate}" >
</input:AutoCompleteBox>

Then we just need to add a little bit of code behind to load it up.

var context = dds.DomainContext as SuperEmployeeDomainContext;
originFilterBox.ItemsSource = context.Origins;
context.Load(context.GetOriginsQuery());

Hitting F5 gives us this…

image_thumb[43]

Validating Data Update

Now – that was certainly some rich ways to view data, but business apps need to update data as well.  Let’s look at how to do that.   First replace all the xaml below the DDS with this… it gives us a nice master-details view.

   1: <StackPanel  Style="{StaticResource DetailsStackPanelStyle}">
   2:  
   3:                    <activity:Activity IsActive="{Binding IsBusy, ElementName=dds}">
   4:                        <StackPanel>
   5:                            <StackPanel Orientation="Horizontal" Margin="0,0,0,10">
   6:                                <TextBlock Text="Origin: " />
   7:  
   8:                                <input:AutoCompleteBox  x:Name="originFilterBox" Width="338" Height="30"
   9:                                                    ValueMemberBinding="{Binding Name}" 
  10:                                                    ItemTemplate="{StaticResource OriginsDataTemplate}" />
  11:                            </StackPanel>
  12:  
  13:                            <data:DataGrid x:Name="dataGrid1" Height="380" Width="380" 
  14:                                           IsReadOnly="True" AutoGenerateColumns="False" 
  15:                                           HorizontalAlignment="Left" 
  16:                                           HorizontalScrollBarVisibility="Disabled"
  17:                                           ItemsSource="{Binding Data, ElementName=dds}" 
  18:                                       >
  19:                                <data:DataGrid.Columns>
  20:                                    <data:DataGridTextColumn Header="Name" Binding="{Binding Name}" />
  21:                                    <data:DataGridTextColumn Header="Employee ID"  Binding="{Binding EmployeeID}" />
  22:                                    <data:DataGridTextColumn Header="Origin"  Binding="{Binding Origin}" />
  23:                                </data:DataGrid.Columns>
  24:                            </data:DataGrid>
  25:  
  26:                            <data:DataPager PageSize="13" Width="379" 
  27:                                            HorizontalAlignment="Left"
  28:                                            Source="{Binding Data, ElementName=dds}" 
  29:                                            Margin="0,0.2,0,0" />
  30:  
  31:                            <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
  32:                                <Button Content="Submit" Width="105" Height="28"
  33:                                    />
  34:    
  35:  
  36:                                <!--new emp button here-->
  37:  
  38:  
  39:                            </StackPanel>
  40:  
  41:                        </StackPanel>
  42:                    </activity:Activity>
  43:  
  44:                    <StackPanel Margin="35,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Height="498" >
  45:                        <dataControls:DataForm x:Name="dataForm1" Height="393" Width="331"
  46:                               VerticalAlignment="Top"       
  47:                               Header="Product Details"
  48:                               CurrentItem="{Binding SelectedItem, ElementName=dataGrid1}" 
  49:                                HorizontalAlignment="Left" >
  50:                            <dataControls:DataForm.EditTemplate>
  51:                                <DataTemplate>
  52:                                    <StackPanel>
  53:                                        <dataControls:DataField>
  54:                                            <TextBox Text="{Binding Name, Mode=TwoWay}" />
  55:                                        </dataControls:DataField>
  56:                                        <dataControls:DataField>
  57:                                            <TextBox Text="{Binding EmployeeID, Mode=TwoWay}" />
  58:                                        </dataControls:DataField>
  59:                                        <dataControls:DataField>
  60:                                            <TextBox Text="{Binding Origin, Mode=TwoWay}" />
  61:                                        </dataControls:DataField>
  62:                                        <dataControls:DataField>
  63:                                            <TextBox Text="{Binding Sites, Mode=TwoWay}" />
  64:                                        </dataControls:DataField>
  65:  
  66:                                        <dataControls:DataField>
  67:                                            <TextBox Text="{Binding Gender, Mode=TwoWay}" />
  68:                                        </dataControls:DataField>
  69:  
  70:                                        <dataControls:DataField>
  71:                                            <TextBox Text="{Binding Publishers, Mode=TwoWay}" />
  72:                                        </dataControls:DataField>
  73:                                        <dataControls:DataField>
  74:                                            <controls:DatePicker Text="{Binding LastEdit, Mode=OneWay}"></controls:DatePicker>
  75:                                        </dataControls:DataField>
  76:                                        <dataControls:DataField>
  77:                                            <TextBox Text="{Binding Issues, Mode=TwoWay}" />
  78:                                        </dataControls:DataField>
  79:                                    </StackPanel>
  80:                                </DataTemplate>
  81:                            </dataControls:DataForm.EditTemplate>
  82:  
  83:  
  84:                        </dataControls:DataForm>
  85:  
  86:  
  87:  
  88:                        <!--Permalink here-->
  89:  
  90:                    </StackPanel>
  91:  
  92:  
  93:                </StackPanel>
   

Through line 35, this is pretty much the same as what we had. 

Then in line 38, we add a DataForm control that gives us some nice way to view and edit a particular entity. 

Hit F5

image

This looks like the traditional master-details scenario.

image_thumb[44]

Notice as we change items they are marked as “Dirty” meaning they need to be submitted back to the server.  You can make edits to many items, unmake some edits and the dirty marker goes away. 

Now we need to wire up the submit button. 

   1: private void SubmitButton_Click(object sender, RoutedEventArgs e)
   2: {
   3:     dataForm1.CommitEdit();
   4:     dds.SubmitChanges();
   5: }

We first need to commit the item we are currently editing, then we just submit changes.  This batches up the diffs and sends them back the server.  and our Update method is called.  Notice the dirty bit goes away.

Now, that is cool, but what about Data Validation?  Well, “for free” you get type level validation (if the filed is typed as an int you and you enter a string you get an error). 

image_thumb[46]

Now let’s see if we can add a bit more.  We do that by editing the SuperEmployeeDomainService.metadata.cs on the server.  It is important to do it on the server so that the system does all the validations are done once for a great UX experience and then again on the server for data integrity.  By the time your Update method is called on your DomainService you can be sure that all the validations have been done. 

Here are some of the validations we can apply.. 

[ReadOnly(true)]
public int EmployeeID;
 
public EntityState EntityState;
 
[RegularExpression("^(?:m|M|male|Male|f|F|female|Female)$", 
    ErrorMessage = "Gender must be 'Male' or 'Female'")]
public string Gender;
 
[Range(0, 10000,
    ErrorMessage = "Issues must be between 0 and 1000")]
public Nullable<int> Issues;
 
public Nullable<DateTime> LastEdit;
 
[Required]
[StringLength(100)]
public string Name;

Just rebuilding and running the app gives us great validation in the UI and in the middle tier. 

image_thumb[48]

Notice how I can navigate between the errors and input focus moves to the next one. 

That was updating data, what about adding new data?

To do that, let’s explorer the new Silverlight 3 ChildWindow.

Right click on Views and add new Item Child Window

image_thumb[50]

Let’s wire it up to show the default window. First add a button to the main form to display the childwindow we just created.

<Button Content="Add New" 
        Width="105" Height="28"
        Margin="5,0,0,0" HorizontalAlignment="Left"
        Click="AddNew_Click" ></Button>

Then wire it up..

private void AddNew_Click(object sender, RoutedEventArgs e)
{
    var w = new AddNewWindow();
    w.Show();
}

image_thumb[51]

Notice it already has a OK and Cancel buttons and a close box that work great right out of the box.  We just need to add a DataForm.  Because we are bound to the same model, the DataForm will pick up all the same features as the update one we just looked at.

<dataControls:DataForm x:Name="newEmployeeForm" Height="393" Width="331"
                       VerticalAlignment="Top"    
                       CommandButtonsVisibility="None"
                       Header="Add New Super Employee"
                        HorizontalAlignment="Left" >
    <dataControls:DataForm.EditTemplate>
        <DataTemplate>
            <StackPanel>
                <dataControls:DataField>
                    <TextBox Text="{Binding Name, Mode=TwoWay}" />
                </dataControls:DataField>
                <dataControls:DataField>
                    <TextBox Text="{Binding EmployeeID, Mode=TwoWay}" />
                </dataControls:DataField>
                <dataControls:DataField>
                    <TextBox Text="{Binding Origin, Mode=TwoWay}" />
                </dataControls:DataField>
                <dataControls:DataField>
                    <TextBox Text="{Binding Sites, Mode=TwoWay}" />
                </dataControls:DataField>
                <dataControls:DataField>
                    <TextBox Text="{Binding Gender, Mode=TwoWay}" />
                </dataControls:DataField>
                <dataControls:DataField>
                    <TextBox Text="{Binding Publishers, Mode=TwoWay}" />
                </dataControls:DataField>
                <dataControls:DataField>
                    <controls:DatePicker Text="{Binding LastEdit, Mode=OneWay}"></controls:DatePicker>
                </dataControls:DataField>
                <dataControls:DataField>
                    <TextBox Text="{Binding Issues, Mode=TwoWay}" />
                </dataControls:DataField>
            </StackPanel>
        </DataTemplate>
    </dataControls:DataForm.EditTemplate>
</dataControls:DataForm>

Now, in code behind we need to write this up by adding a class level field..

public SuperEmployee NewEmployee { get; set; }

..initializing the instance in the constructor

 
            NewEmployee = new SuperEmployee();
            NewEmployee.LastEdit = DateTime.Now.Date;
            this.newEmployeeForm.CurrentItem = NewEmployee;

..handling the OK button

private void OKButton_Click(object sender, RoutedEventArgs e)
{
    newEmployeeForm.CommitEdit();
    this.DialogResult = true;
}

image_thumb[54]

Great… now let’s commit this change locally.

void addNewWindow_Closed(object sender, EventArgs e)
{
    var win = sender as AddNewWindow;
    var context = dds.DomainContext as SuperEmployeeDomainContext;
    if (win.DialogResult == true)
    {
        context.SuperEmployees.Add(win.NewEmployee);
    }
}

From this, the Submit button will send this change to the server.

Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 1: Navigation Basics

With Silverlight 3 shipping and a brand new update to .NET RIA Services I thought I would update the example from my Mix09 talk “building business applications with Silverlight 3”.

You can watch the original  video of the full session 

The demo requires (all 100% free and always free):

  1. VS2008 SP1 (Which includes Sql Express 2008)
  2. Silverlight 3 RTM
  3. .NET RIA Services July '09 Preview  (optional for this part of the demo)

Also, download the full demo files and check out the running application.

Today, we will talk about Professional Feel.. 

Professional Feel

Business applications need to have a professional, but how many of us have a full time designer on our staff?  I’d guess very few.  That is why we invested in a great out of box experience.  The Silverlight Navigation Application and Silverlight Business Application (which adds login\logout support) project starts with  a clean, prescriptive application structure, a nice look and feel, and is very easy to customize, even for a developer.

File\New Project – Silverlight Business Applications

image

Hit F5

image

Change from Mix: Notice the cool new, clean, light default template. 

This is a full frame Silverlight Application.  Notice the navigation links (home and about).

image

Notice the forward and back in the browser works…  

image

And there is a deep link, that navigates you back to exactly this point in the application.  You can cut and paste it into a blog entry, an email or an IM to your co-works and they will be taken to exactly the same point in the app.

image

… no mater what browser they are using.

Now, even the best developers sometimes make errors in applications.  Links that are invalid or exceptions that get thrown.  The Navigation Application Template makes it super easy to deal with those.      Type in a bad URL and look at the experience (be sure to run in retail). 

image

Now, let’s go in and look a bit of customization. 

First, let’s add a new page. 

Right click on Views in the client project and Add New Item, Select Silverlight Page.

image

image

When the page opens, add some simple text..

<TextBlock Text="Hello World!"></TextBlock>

Now, let’s wire up the this page to the main navigation menu.  In MainPage.xaml, add a new button following the same format as the ones that are there.

<Rectangle Style="{StaticResource DividerStyle}"/>
 
<HyperlinkButton Style="{StaticResource LinkStyle}" 
                 NavigateUri="/MyFirstPage" 
                 TargetName="ContentFrame" 
                 Content="my page"/>

Now, while we are in there, let’s customize the error window template… Open Views\ErrorWindow.xaml.  You can change the format, log the error back to the server or customize the text on the error message the end user sees. 

<TextBlock x:Name="IntroductoryText" Grid.Row="0" Margin="0" 
           Text="An unknown error was encountered. Please contact ScottGu anytime day or night (123) 332-9801 for more information." 
           Width="398" TextWrapping="Wrap" HorizontalAlignment="Left"/>

Now, let’s update the branding for this site.  First in MainPage.xaml, change the name from “Application Name” to something custom to your app. 

<TextBlock x:Name="ApplicationNameTextBlock" Style="{StaticResource ApplicationNameStyle}" 
                   Text="Super Employee Placement Service"/>

Finally, let’s go in and change the colors to match your companies branding.    Open up the Styles.xaml file in Assets folder.  While all the styling is there for you to customize, we made a few of the common properties easy to find and change even for a developer.

image

Fit F5 and see what we have….

image

image

As you can see, my color choices aren’t great, so it is good that we are shipping a whole library of app.xaml files for you to choice from.    If you just drag one of the light, clean ones..  hit F5..

You can get all the latest themes from here.. they work just great from VS as well as expression! 

http://timheuer.com/blog/archive/2009/07/09/free-silverlight-application-themes-silverlight-3.aspx 

Aurora (also available for RIA Services Template):

Aurora app theme

Frosted Cinnamon Toast:

Frosted Cinnamon Toast app theme

Lime Shocker (also available for RIA Services Template):

Lime Shocker app theme

Pinky (also available for RIA Services Template):

Pinky app theme

Retro:

Retro app theme

Skyline:

Skyline app theme

Subdued:

Subdued app theme

Posted 10 July 09 10:06 by BradA | 4 Comments   
Filed under , ,
.NET Rocks! on Data Access Options

Recently .NET Rocks! talked to Stephen Forte and covered a topic I have been interested in for a a couple of years: Data Access Options.  Clearly this has been a space of a lot of innovation in the last few years.  Stephen does a good job of explaining the benefits customers are getting out of that innovation but he also gives us at Microsoft a few points to consider on the technology options.

imageOf course one of my favorite parts starts right at the end when Richard asks Stephen about .NET RIA Services. It is about at minute 47 if you want to skip ahead to it ;-).    Stephen clearly sees RIA Services as more than Silverlight as it hooks into ASP.NET… he also sees how it shields the developer from the unnecessarily complex code. 

Enjoy!

Posted 09 July 09 10:05 by BradA | 0 Comments   
Filed under ,
New MSDN Article on RIA Services Published

I saw Maurice de Beijer recently published a good introduction article on .NET RIA Services.  image

Getting started with the .NET RIA Services

The post starts with a very good introduction:

RIA, short for Rich Internet Applications, is a bit of an umbrella term for all sorts of applications delivered through the browser. The key aspect however is that they deliver some business function and are not just about flashy graphics. Business applications tend to work with data and other business resources so they are usually built in the standard N tier architecture. If we take a look at this N tier architecture for the most common type of business resource, the database, we typically see the Create, Read, Update, Delete, (CRUD) pattern appear all the time. While implementing the CRUD pattern in Silverlight isn’t extremely difficult the very fact that the Silverlight application runs in the browser without direct database access and all server communication is done asynchronously makes this harder than it needs to be. This is exactly one of the problems the .NET RIA Services is trying to solve. Of course there is more to the .NET RIA Services and the standard CRUD operations is just one of the issues addressed. As we will see in this article it addresses much more by including things like data validation, general communication, keeping client and server code synchronized and more.

When evaluating the .NET RIA Services we should be looking at it from two different perspectives. First of all it is a set of design guidelines of how to create a RIA style application. Secondly it is a series of .NET libraries and Visual Studio templates implementing the design guidelines. So even if you don’t want to use the .NET RIA Services binaries, studying the design is very useful for a Silverlight line-of-business (LOB) developer. Another thing to keep in mind when evaluating the .NET RIA Services is that it is not just about Silverlight but more general. The first samples may be with Silverlight clients but a client could equally well be written in ASP.NET/JavaScript, WPF or any other client that can call WCF services.

Enjoy!

Posted 30 June 09 05:05 by BradA | 0 Comments   
Filed under
Unit Testing with .NET RIA Services

Vijay, one of the folks working on RIA Services recently posted a very good overviewimage of how to do Unit Testing with .NET RIA Services.  I think this is an important benefit of adopting the RIA Services pattern. 

Check it out and let us know what you think!

 

Unit Testing Business Logic in .NET RIA Services

Posted 26 June 09 11:39 by BradA | 1 Comments   
Filed under ,
PM Tip #10: Interview Tips for Landing a Great Program Management Job

image Recently a friend of mine at Microsoft asked about tips for how to land a great Program Management job at Microsoft.    It has been a while since I did a “PM Tips” post, so I thought I’d use the opportunity to share my thoughts and get your feedback.

I have done lots of PM interviews over the years and through the process I have developed a few things I look for to spot great program managers.  In fact I have often mentioned to co-workers in Dev or test and even people I meet at social events that they would be great PMs… most of the time they look at me like I am crazy… but sometimes, they turn out to be, in fact, really great PMs.

Getting the Interview

Know what you are looking for – Given this economy, I know many folks just want *a* job.  But I’d encourage you to think more deeply about it.  You are more likely to land a job that allows you to use your discretionary effort – that is, something you will LOVE doing.   Another way to look at this is for every job you apply for, know why *that* job is great for you.  So while you could apply for many jobs, you want to figure what makes you interested in each one.  Is it the people you’d work with, the technology, the role? 

image Understand why you are looking – There are lots of good and bad reasons to look for a new job.  Be sure the check your motives.  Hiring managers don’t want to get a “problem” employee that runs away from hard problems or can’t get along with co-workers, etc.  Good hiring managers will want to really find out what is motivating you to look now.  Even if it is something like a “unfair” review or a disconnect with your manager that is making your want to look, I’d encourage you to think hard about the root cause – for example maybe your review isn’t great, in part because you have lost passion for the an area you have worked in for long time.  

Network – Chances are very good that someone you know knows your future boss.  Put the word out that you are looking.  If anyone on my team recommends someone for a position, I always do at least an informational with them… the same is certainly not true for the cold calls I get.    Be sure you have talked to your management chain about this first as news travels fast.  You don’t want to surprise anyone.  It is always best if you can tell your management chain that your first option is to stay with the larger team… that motives them to find a role for you and helps you not look like you are running away.

The Cold Call – Sometimes you will have to do a cold call – just reply to an open position even when you have no personal connection.   Don’t let this stop you from your dream job.  But do do your research.  In your first mail to the hiring manger mention why you are interested.  is it the technology, the people, or some aspect of the role?  Specifically ask for sometime with them or someone on their team to talk more about the job.

Do your homework – In the days of Bing, Google, Blogs, Twitter and Facebook it is very easy to find information on people and projects.  Who are you going to interview with?  Find out what their last talk at a conference was, what was their last blog on, have they done a blog post on interview tips ;-)  etc.  For the project, what is the core message, what are customers saying?  what are the big problems?  Is there a beta or CTP of the product you can play with a bit?  Can you get some first hand experience with the product.

 

The Interview Process

The overall interview process can be time consuming and take a lot of elapsed time.  And while you can try to put a schedule on it, the truth is it will take as long as it takes.  This is a big decision for both you and the hiring manager.  Here are a few things to expect in roughly this order:

1. Initial Informational – this is usually with the hiring manager or someone she respects.  The goal here is mostly a “get to know you”. 

2. Follow up informationals\informal interviews.  Committing to an interview day is big for both of you.  You have to tell your current manager (if you are already an employee at MS) and the hiring manager has to invest several hours in an interview loop and discussions.  Often you both want to raise confidence before doing a loop.     I am a big fan of these as they give you a very good idea of what the loop will be be like.  It is very much a trial run. 

3. The Loop – If all goes well, eventually you will do a full day interview loop.  You are likely to talk to 3-6 of your co-workers, your boss peers, etc.  Be sure to ask each of them what their relationship is to the hiring manager.  Begin to form of map of the organization.  image

4. The hire\no-hire decision – often this is very quick.. a matter of a couple of days for the hiring manager to compare notes with the interviewers and make a decision. 

5. Accepting the offer – You need to formally accept the offer.  My suggestion is that you loop back one more time with your current team before formally accept… again you want to leave on the best terms as possible. 

 

In the Interview

Good answers to stock questions – I always ask a few stock questions: 
Why is now a good time to look?   Good reasons would be product shipping, significant change in directions, etc.  Bad reasons would be you got a bad review, a reorg didn’t go your way, etc. 
Why this role?  Good reasons would be following your passions for technology X or part of a progression (from low-level to high-level platform for example, or it could be the people, etc.  Bad reasons would be you want to be the boss, you want an easier\less stressful job, etc.
Why PM?    Good reasons would be around wanting breadth of scope, impact the product, customer connections, etc.  Bad reasons would be to make decisions or be in charge. 

 

Tell me about a time…  - I love to hear about the personal experiences of interview candidates.  What have they really been through and what have they learned?  To get at this I often ask Tell me about a time you made an unpopular decision, made a big mistake, managed someone out of the company, etc.   Have a few stories ready for this sort of thing.  Think of a few “big” issues you have dealt with recently and what you have learned – likely this event can cover no mater what the “tell me about…” opener is.  Just be sure you know what the point is you are making.  That you learned quickly, that you stand your ground under pressure, that you know how to work cross group into a win-win situation. 

imageIndustry Questions – I often ask candidates about the software industry to see how much they are keeping up.  Sometimes I ask candidates about the industry around their current role.  Here I am looking to understand how deeply they seem to understand the industry.  For example, if they are coming from SQL Server, do they talk about the industry around one version of SQL to the next or do they talk about it in terms of Oracle and MySql or do they talk about it in terms of unstructured data storage and how we can mine that in different ways.   I also ask candidates about my area.. how much do they understand about the real business they are interviewing for.  Clearly they are not experts, but I like to know they have done some level of research and thinking.  I also like to push different ideas and see how they react, distill and question.  

Technical Questions – I almost always ask technical questions.  Say a coding question done on the whiteboard or a how technology X works.  My goal here is to see if the candidate can hold their own in a technical conversations.   The main thing to do here is to set exceptions well. For example, if honestly you are not a world's best coder, be sure to tell the interview, but go for it done the less.   Remember this is more about how you think than what you know.  Candidates often freeze up on these sorts of questions.  The best thing you can do is relax and think out loud.  Even ask the interviewer if you are on the right track or not..  Often they want to help you.   

Design a Bahh Questions – Design a ATM for a child or a blender for the blind, etc.  These questions are really about trying to see how creatively you can think and, more importantly, how well you can sift through and winnow down your ideas.  My advice here is to start with questions – ask a bunch of questions to scope out the space and give you time to get inspired.  Get excited about your solution – even as you (and the interviewer) finds holes.  This is a great time to show your passionate about your job. 

Riddles and Trick Questions – It is true – Microsoft does often ask “why are manhole covers round” sort of questions.  I have found the main value here to be on the candidates attitudes.  Don’t belittle or doge the question.. again, show you are game and go for it.  It is very unlikely that this is a simple pass\fail test, so worry less about the getting the right answer at the end and more about the process of getting there.

Your Questions – I typically end the interview by asking if the candidate has any final questions.  This is your last chance to make a good impression.  Ask good questions that shows you have done your homework.  Does the interviewer see the industry trends the same way you do (or you have read about)?  what are they doing about top issues in their product that you know about (or have read about)?  How is their cross group interactions?  The best questions are the ones that you sincerely have… after all, it is a big bet for you as well. 

After the interview

Just like your mom probably taught you it is a good idea to follow up with your interviewer the next day mostly just to say thanks for the interview.  The truth is very likely their hire-no hire decision has been made already, so you are not going to change that.  But it is a small world, so a good last impression is important.  One thing I appreciate is when I am able to get a candidate sufficiently interested in a question that they think about it later.  So in the follow up interview you might mention you thought about it more and you have X to add or you solved the coding question and here is the answer.  Again, you are very, very unlikely to change the outcome of the interview from this, but it is a nice touch.

image

 

 

What do you think?  If you often hire PMs at Microsoft, what would you add?  If you have recently been through a loop, would any of this have helped?

Posted 24 June 09 02:33 by BradA | 12 Comments   
Filed under
A new generation of programmers begins

I have started teaching my 6-year old son logo as our summer learning project.  My goal is to help him discover the creativity and logical thinking approach that programming requires. And, of course to share a passion that I have with him, so there is a tiny hope we will have something to talk about when he is a teenager. ;-)

Anyway, tonight he just finished his ‘real’  first program!  A bit of it was copied from an example and some of it was inspired from watching me play around, but really it was all his idea. 

 

Bostons first logo program

Oh, and you Framework Design Guidelines fans – don’t worry, names like “tri” and “wee” will not last.. what is the naming conventions for Logo anyway?  (btw, “wee” is short for pinwheel and tri of course is triangle)

We are using FMSLogo… it is fine, but we’d be happy to move to a .NET version if you can recommend something.

Have you taught child programming?  how did it go?  what did you use?

Posted 09 June 09 08:16 by BradA | 49 Comments   
Filed under
Release Roadmap for .NET RIA Services

image Dinesh Kulkarni recently posted our current thinking on the release roadmap for .NET RIA Services.   One thing I love about this product is that we are able to iterate rapidly with the community to get the product right.  This means being in “preview” mode for a while so we can ensure we have taken all the feedback, but it greatly raises the likelihood of us ending up with a product that can be widely used.   We used a similar model with ASP.NET MVC and MEF, and I think they turned out really well. 

So please give us your feedback as you try out drops of .NET RIA Services.  As we mention in the post, we are enabling go-live with our next CTP, so that should enable more folks to use it in production (though I know some of you already are!). 

.NET RIA Services V1 CTPs: current thinking

Posted 09 June 09 06:44 by BradA | 5 Comments   
Filed under
Silverlight 3 and .NET RIA Services Keynote at VSLive!

I just finished up the keynote at VSLive in Vegas.     I did an update of my Building Amazing Business Applications with Silverlight 3 talk from Mix09.  I updated to the latest internal builds of Silverlight 3 and .NET RIA Services late last week for this demo.  It was very fun to see stuff come together an improve.  There are some great updates to the Navigation Application template, navigation in general, authentication, master-details databinding, dataform and much more that makes this demo even more smooth. 

I will do a blog post with all the code as soon as Silverlight 3 RTMs. 

image

Posted 08 June 09 10:18 by BradA | 11 Comments   
Filed under ,
Forms Auth\Windows Auth – what is more common?

I was talking to some coworkers today about the scenarios for Forms Auth and Windows Auth in line of business applications.    We were having a debate about which was more common.

As you might guess at Microsoft we are an all windows shop, so just about all our line of business applications use Windows auth, and I gotta say it is pretty nice not to have to remember a bunch of user names and passwords.  

But I wonder if that is so common across the industry.. and even for companies that do use Windows Auth, I imagine there are scenarios where Forms auth is still important. 

One place this manifests itself is in the project templates  for things like ASP.NET MVC, ASP.NET WebForms, Silverlight, etc.  Should we be wiring these up to support Forms Auth by default (with a log in\register controls) or Windows Auth where those are not needed?

Here is a little forms auth example… 

image

 

What do you think?  What is more common in your experience Forms auth or Windows Auth?

Posted 04 June 09 10:39 by BradA | 89 Comments   
Filed under ,
Survey: Ajax usage among .NET developers in 2009

image A couple of years ago Simone Chiaretta did a survey of .NET Developers usage of Ajax..   I just saw that he is refreshing that survey to see what has changed in the industry.  Are people still actively moving to Ajax?  Are they using MVC or WebForms with their Ajax?  Which ones of the *many* ajax frameworks out there are they using?  Feel free to write-in Silverlight if that is your current preference for this style of application. 

Very interesting data… and while clearly not a scientific survey, it is an interesting data point as Simone has agreed to publish all the data he gets.   Here is what he has so far.

So please take a few minutes and fill out the survey and pass it on to your colleagues.

http://www.zoomerang.com/Survey/?p=WEB22973CYKW2H

Posted 27 May 09 08:25 by BradA | 5 Comments   
Filed under ,
.NET RIA Services: Get your metadata from anywhere!

While the feedback on .NET RIA Services has been great, many people have commented on the way we store metadata as custom attributes on “buddy” classes of entities. 

For example, in my Mix demo to get automatic validation like this:

image

 

I had to provide metadata on my entity class on the server like this:

image  
 

This is very cool and I believe works just fine in a lot of scenarios.  But sometimes you want to pull metadata from another source.  For example from a database or from calling a web service or by looking in an external metadata file. 

So with the .NET RIA Services May Preview we added a neat little sample that shows how to build your own metadata provider and a specific implementation that works with an external metadata file.  I’d expect you can pick up this sample and pretty easily update it to pull the metadata from your database or any other data source whenever the client XAP file is built.    

For example, this validation form…

image

Is driven from this xml..   Again, notice that this is just a sample, and you can define your own format. 

<Metadata xmlns="http://schemas.microsoft.com/riaservices/metadata/2009">
  <MetaType Type="DomainModel.Product">
    <MetaProperty Name="ProductCode">
      <MetaAttribute Type="Key"/>
      <MetaAttribute Type="Required"/>
      <MetaAttribute Type="CustomValidation">
        <Argument Type="Type" Value="TestDomainValidator"/>
        <Argument Type="string" Value="ValidateProductCode"/>
      </MetaAttribute>
    </MetaProperty>
    <MetaProperty Name="Name">
      <MetaAttribute Type="StringLength">
        <Argument Type="int" Value="50"/>
        <Property Name="MinimumLength" Value="10"/>
      </MetaAttribute>
    </MetaProperty>
  </MetaType>
</Metadata>

 

Check out the full sample or just the doc file explaining it and see the many other great .NET RIA Services based samples.

Posted 26 May 09 04:08 by BradA | 13 Comments   
Filed under ,
.NET RIA Services at TechEd 2009

Scott Morrison just published his demo files for his talks at Teched..  He did some great work on to of the SuperHeros demo we did at Mix09.

Get all the Tech Ed 2009 Demo Files

image

Posted 18 May 09 02:33 by BradA | 5 Comments   
Filed under
The DZone interviews Hamilton Verissimo on MEF

image The DZone has a nice interview with Hamilton on MEF

Microsoft MEF Q&A with Hamilton Verissimo de Oliveira

Hamilton is one of our PMs here at Microsoft as well as the creator of the very popular Castle Project and he will tell you what the core value of MEF, tell you if MEF a DI container or not and get you versed in the MEF terminology. 

Read and Enjoy!

Posted 12 May 09 08:24 by BradA | 4 Comments   
Filed under
.NET RIA Services May 2009 Preview

Today we posted a minor update to .NET RIA Services.  This release is mainly focused on addressing bug fixes we have heard in the forums and delivering on a few key areas… There are a lot of other long lead work items that will fall into future releases. 

Download it today from: http://code.msdn.microsoft.com/RIAServices 

Here is a list of what is available in the May 2009 Preview:-

  1. Tons of bug fixes. Most of the bugs reported in the forum have been addressed.
  2. New Business application Template… This template adds login\create new user to the Silverlight Navigation Application template.

    image

    imageimage   

  3. Authentication Sample
  4. XML Metadata provider Sample…  We have heard very clearly that folks want an option to store validation metadata outside of custom attributes.  This sample shows how to find metadata in an Xml file, but you could easily extend to find validation information from a database.
  5. Linq2Sql Domain Provider Sample..  Out of the box we support POCO (plain old CLR object), Linq2Sql and Entity Framework, but we know folks are actively looking into building support for nHibernate, Sharepoint, etc.   This is a great sample that shows you the ends and outs of writing a provider.  It is the actual product code we use for the Linq2Sql provider (plus a little clean up).
  6. Updated asp:DomainDataSource that works great with asp Dynamic Data

All the samples (March 2009 and May 2009) can be found at http://code.msdn.microsoft.com/RIAServices

We’d love to hear what you think and what you’d like to see in the next preview!

More Posts Next page »

Search

Go

This Blog

Syndication

Page view tracker