Follow @PDSAInc Paul Sheriff's Blog for the Real World

Paul Sheriff's Blog for the Real World

This blog is to share my tips and tricks garnered over 25+ years in the IT industry

Paul's Favorites

Join me on Thursday, April 10th in Nashville

Hi All,

If you are in the Nashville, TN area, I hope you will join me at the Nashville .NET User Group http://nashdotnet.org/ for a seminar entitled "Best Practices for Flexible Code".

Seminar Description

Creating applications that are flexible and maintainable means thinking about application development a little differently. You need to adopt good object-oriented techniques in order to create software that can truly adapt to a changing development environment. In this seminar you will see many examples of tips and tricks that will help you keep your software running for many years to come. You will see real-world examples of extension methods, faster reflection, string handling, generics, using XML, wrapper classes, dependency injection, configuration and exception management. You will walk away with a code that you can use in your applications right away.

So, come on out at (http://nashdotnet.org/) at 6pm on Thursday, April 10th, 2014.

Hope to see you there!

Paul Sheriff

 

 

Posted: Apr 09 2014, 07:19 PM by psheriff | with no comments
Filed under: ,
WPF for the Visual Basic Programmer - Part 2 (Pluralsight)

Hi All,

I have just published a new course on www.pluralsight.com. Check it out! 

Visual Basic Programmers are still in demand. Upgrade your skills by learning XAML and WPF. This course is specifically designed for the Visual Basic programmer and will get you up to speed quickly with WPF. In Part 2 you will learn the correct way to design WPF windows, how to use styles and all the most commonly used controls for business applications. You will gain a good knowledge of data binding and how to use the various list controls in WPF.

http://pluralsight.com/training/Courses/TableOfContents/wpf-vb-programmer-pt2

Enjoy!

Paul

 

Put Development Standards In Place At Your Shop

Before beginning any application development consider implementing programming and database standards with your team. Using development standards allows all programmers to know what is expected of them and how to create new applications from scratch. Standards help developers move from one project to another without having to learn a different style of programming because it was created by another programmer.

There are many reasons programming standards are created. Many years ago when mainframes were in vogue, every shop had programming standards. In fact, they used to teach programming standards in college. Now, standards are all but forgotten or just never learned by the younger generation. Microsoft does have a set of programming standards for C# and Visual Basic. These are an excellent place to start, and I would like to encourage all programmers today to adopt some sort of standards as an important first step in application development.

Creating standards does not limit your creativity as most programmers seem to think. Programming standards help you focus your creativity where it is really needed. You concentrate on the business problem you are trying to solve, instead of having to always think about what name to give a method or variable. As a corollary, consider the Windows and Mac operating environments where most programs written have a consistent look and feel. This is why users like using Windows or Macs, because they do not have to learn everything about how a new program works. They already know how to use most of the features in each program. Utilizing standards in your programming, you keep the programmer’s “look and feel” consistent. You will spend less time figuring out what the variables are or how many indents a programmer used, and you can focus more on the logic of the program.

The use of standards lead to reduced maintenance costs as well, due to consistency in each program. You can move from one project to another very easily, even one someone else wrote, and immediately read and understand the code. Programming standards help programmers create a consistent structure, code style, variable names, and methods names within all applications. Standards also help programmers create code that is unambiguous, easy to read, and easy to maintain by other developers.

The standards documents you should have in place at your shop are Visual Studio Setup, C# or Visual Basic Programming Standards, SQL Server Object Naming Standards and Database Development Standards. The rules set forth in these documents are guidelines, so feel free to modify these to suit your own organizations’ needs.

  • The Visual Studio Setup document is used to ensure each programmer configures their Visual Studio the same as everyone else in the shop. Especially important is the Tab setting so everyone uses the same tab indent. If different programmers use different tabs and they get changed, this can wreak havoc on your source control.
  • The C# or Visual Basic Programming Standards document will set forth variable and method naming, class naming, file naming, control naming and many other standards.
  • The SQL Server Object Naming Standards document describes how to name tables, stored procedures, views, and other database objects. You should also describe how SQL keywords and functions in your SQL statements are cased.
  • The Database Development Standards document describes your database design philosophy. Your philosophy may include things such as how you create primary keys, the use of clustered indexes, standard fields for each table, how to handle concurrency, and whether or not to use dynamic SQL or stored procedures.

You can find examples of all of these standards documents at my website: http://www.pdsa.com/download/StandardsDocuments.zip

We have definitely found that having programming standards in place at our shop has been a positive thing. I hope they work equally as well for you.

WPF for the Visual Basic Programmer (Pluralsight)

Hello All,

I have just published a new course on www.pluralsight.com! Check it out!

WPF For the Visual Basic Programmer

Visual Basic Programmers are still in demand. Upgrade your skills by learning XAML and WPF. This course is specifically designed for the Visual Basic programmer and will get you up to speed quickly with WPF. In Part 1 you will learn the correct way to design WPF windows, how to use styles and all the most commonly used controls for business applications. You will gain a good knowledge of data binding and how to use the various list controls in WPF.

http://pluralsight.com/training/Courses/TableOfContents/wpf-vb-programmer-pt1

 

Pluralsight Class on Best Practices for Requirements Gathering

Hello All,

My Vice President, Michael Krasowski, has published his first course on Pluralsight!

Best Practices for Requirements Gathering

This course begins with the fundamentals of the requirements process, including project definition template, the uncertainty of requirements, nailing down stakeholders, and the skills needed to be a requirements analyst. Next we explore how requirements gathering in an Agile environment works. And lastly, we review practical tools to guide the student from user cases/stories, work flows, mockups, business rules, and data model to produce a solid specification that meets a customer's expectations.

Check it out at: http://pluralsight.com/training/Courses/TableOfContents/best-practices-requirements-gathering

Paul

Two more courses on Pluralsight

Hello All,

I am pleased to announce that I have released two more courses on Pluralsight.com.

How to Start and Run a Consulting Business

Have you ever wanted to break out of the corporate life and be your own boss? Many people have this dream. In this course you will learn what it takes to start and be successful in your own consulting business. Throughout this video you will learn how to determine what your company should look like, how to manage your money wisely, how to get and keep clients, how best to survive the ups and downs of the economy and how to create an exit strategy. Your instructor has been running his own successful business for over 22 years and shares his valuable insight so you too can be a success!

Module 1: Hanging Your Shingle
Module 2: Money Matters
Module 3: How to Get and Keep Clients (or Marketing 101)
Module 4: How To Survive the Ups and Downs
Module 5: Creating an Exit Strategy

http://pluralsight.com/training/Courses/TableOfContents/start-run-consulting-business


WPF for the Business Programmer
There are so many cool things you can do with WPF that would be impossible or very difficult with Windows Forms. In this video you will see some creative ways to use the WPF List Box. Some screens that you can use right away in your business applications will be presented. You will learn some unique ways to put together user controls to create unique shapes. Finally you will create a shell application to make your WPF application look like Windows 8. This course goes way beyond the basics of WPF to give you some unique insights on how to create business applications.

Module 1: The Flexible WPF List Box
Module 2: More Fun with the WPF List Box
Module 3: Develop Business Application Screens in WPF
Module 4: Create WPF Shapes with Text
Module 5: Creating a Windows 8 Shell in WPF

http://pluralsight.com/training/Courses/TableOfContents/wpf-business-programmer


And of course, my first course is:

The Many Approaches to XML Processing in .NET Applications

Did you know that you can use XML instead of a SQL database for applications? Did you know there is LINQ to XML that allows you to process XML documents quickly and efficiently? If the answer is no to either of these two questions, then you need to watch this course. XML files are very common in today's programming world. You will most likely need to read files, write files and query XML within your applications. .NET provides a rich set of XML processing classes that you can use to perform all these functions. C# allows you to easily create, read and query XML files using XPath, LINQ to XML and other methods. In this course you will learn to read and write XML files using the various .NET classes. You will see some real-world uses of XML files in applications.

Module 1: What is this XML Thing Anyway?
Module 2: A Myriad of Methods to Read XML
Module 3: 16 Ways to Write XML Documents
Module 4: Real World Uses of XML
Module 5: LINQ to XML Step-by-Step
Module 6: Use XML: An Alternative to SQL


http://pluralsight.com/training/Courses/TableOfContents/xml-processing-approaches-dotnet-applications

Go to www.pluralsight.com and sign up today and start learning! 

Posted: Sep 18 2013, 01:45 PM by psheriff | with no comments
Filed under: , , ,
Create a Login Window in WPF (2013)

 One of my most widely-read blog posts had to do with creating a Login Windows in WPF that I wrote several years ago. I thought I would revisit this login screen with an updated version in Visual Studio 2012 and with an updated look and feel.

Most business applications require some sort of security system. You can always use Windows Authentication to authenticate a user, but sometimes you might want your own authentication scheme. When you do, you will need to create a login screen for your user to enter her login id and password. This article will explore creating a login window in WPF.

The UI for your login screen can contain any images and controls that you would like. In Figure 1 you can see a sample login screen that has an image of a key, a large title label across the top, two labels, a text box, a password box and two button controls. You can also make the border of the window rounded so that there is no close, minimize or maximize button and no title bar.

WPF Login Screen

Figure 1: A Login Screen

Of course this is just one version of a login screen but let’s take a look at how this is put together.

Creating the Window

To start, you need to create a window with no border and can be made into any shape you want. To do this you will set a few different attributes. The WindowStyle attribute normally allows you to set a single border, three-D border, or a Tool Window border. Setting this attribute to None will eliminate the border. The ShowInTaskbar attribute is optional, but if you are building a login screen you probably won’t want this window to show up in the Task Bar as it is going to be modal style form. The next two attributes, AllowsTransparency and Background work together. You must set AllowsTransparency to True to allow the Background to be set to Transparent. If you do not set these two attributes, then your border will still show up. Below is the xaml for this window.

<Window ...
   WindowStartupLocation="CenterScreen"
   AllowsTransparency="True"
   ShowInTaskBar=False
   Background="Transparent"
   WindowStyle="None"
   SizeToContent="WidthAndHeight"
   FocusManager.FocusedElement=
          "{Binding ElementName=txtUserName}">

   ...
   ...

</Window>

There are three additional attributes that are set on this window. The WindowStartupLocation attribute is set to “CenterScreen”  to ensure that the login screen is displayed in the middle of the screen when it is shown. You also set the SizeToContent attribute to WidthAndHeight to just take as much room for this window as the controls need that are contained within this window. The FocusManager.FocusedElement attribute is data-bound to the textbox control next to the User Name label. This tells WPF to place the cursor in this textbox once the screen is displayed.

The Border

Now that you have the Window xaml defined you now can create the look for the outside border of the window. A Border control is used to form the outside of this login screen. You will set the CornerRadius attribute to “10” to give the nice rounded corners. You can set the BorderBrush to “Gray” and the BorderThickness to “3”. You also want to give this border a nice wide Margin to allow room for the DropShadowEffect that we add to the outside of this border. If you do not do this, then the drop shadow will be chopped off.

The DropShadowEffect is created as a resource with a key of “shadowWindow” as shown below:

<Window.Resources>
  <DropShadowEffect x:Key="shadowWindow"
                    Color="Black"
                    Opacity=".75"
                    ShadowDepth="12" />
</Window.Resources>

When you create the Border for this window you set the Effect property to reference this static resource.

<Border CornerRadius="10"
        BorderBrush="#FF5F5F5F"
        BorderThickness="4"
        Background="{StaticResource backBrush}"
        Effect="{StaticResource shadowWindow}"
        Margin="24"
        Padding="24">

Using a Grid Layout

To place each of the login screen elements within the border, a Grid control is used with specific column and row definitions. There are three columns in this login screen. One for the image of the key, one for the labels and one for the TextBox, PasswordBox and Button controls.

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition MinWidth="80" Width="Auto" />
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>

   ...
   ...

</Grid>

Placing the Key Image

The Key image that is in the upper left hand corner of this login screen is placed there by using an Image control. Notice the Grid.Column, Grid.Row and Grid.RowSpan attributes that are set on the StackPanel. The Grid.Row and Grid.Column specify in which row and column of the grid you wish to display the Image control. The Grid.RowSpan allows the key to float down over the next three rows of the Grid control if necessary. If you were to use a smaller or larger key image, then you would probably need to adjust this attribute accordingly. The Image control sets the source of its image to the KeyComputer.jpg file located in the /Images folder. A drop shadow effect is applied to this image control just like you did with the Border control.

<Image Grid.Column="0"
        Grid.Row="0"
        Grid.RowSpan="3"
        Effect="{StaticResource shadowWindow}"
        VerticalAlignment="Top"
        HorizontalAlignment="Left"
        Name="imgKey"
        Width="50"
        Margin="8"
        Source="Images/KeyComputer.png" />

The Large Title Label

The large label across the top of the login screen is simply a TextBlock control within a Border control that has the appropriate Grid.Row, Grid.Column and Grid.ColumnSpan attributes set for placement. A FontSize of 18 is applied to make the text appear larger than the other labels on this screen. A Margin of 10 is used to give us some spacing from the border of the grid.

<Border Grid.Column="1"
        Grid.Row="0"
        Grid.ColumnSpan="2"
        Margin="4,10,4,20"
        CornerRadius="10">
  <Border.Background>
    <LinearGradientBrush EndPoint="0.5,1"
                          StartPoint="0.5,0">
      <GradientStop Color="#FFC7C2C2"
                    Offset="0" />
      <GradientStop Color="#FF8D8787"
                    Offset="1" />
    </LinearGradientBrush>
  </Border.Background>
  <TextBlock FontSize="18"
              Margin="10"
              Text="Please Login To Access This Application" />
</Border>

The Login Controls

The controls that gather the user name and password should be fairly familiar to you if you have been doing any WPF at all. Each control is placed into a specific row and column of the Grid control. Notice the use of the Tooltip attribute on the Login TextBox, the PasswordBox and Domain TextBox control. This gives the user an idea of what to put into each control if they hover their mouse over that control.

<TextBlock Grid.Column="1"
            Grid.Row="1"
            Text="User Name" />
<TextBox Grid.Column="2"
          Grid.Row="1"
          ToolTipService.ToolTip="Enter Your User Name"
          Name="txtUserName" />
<TextBlock Grid.Column="1"
            Grid.Row="2"
            Text="Password" />
<PasswordBox Grid.Column="2"
              Grid.Row="2"
              ToolTipService.ToolTip="Enter Your Password"
              Name="txtPassword" />
<TextBlock Grid.Column="1"
            Grid.Row="3"
            Text="Domain" />
<TextBox Grid.Column="2"
          Grid.Row="3"
          ToolTipService.ToolTip="Enter Domain Name to Login To"
          Name="txtDomain" />

The Buttons

The two buttons at the bottom of the screen are placed into the last row of the Grid control and into the second column of the grid by wrapping them into a StackPanel. The StackPanel has its HorizontalAlignment attribute set to Center and its Orientation attribute to Horizontal to allow the buttons to be centered within the StackPanel and to have the buttons appear side-by-side to each other.

<StackPanel Grid.Column="2"
            Grid.Row="4"
            Margin="4"
            HorizontalAlignment="Right"
            Orientation="Horizontal">
  <Button Name="btnCancel"
          Click="btnCancel_Click"
          IsCancel="True"
          Effect="{StaticResource shadowWindow}"
          ToolTipService.ToolTip="Cancel">
    <Image Source="Images/XBlack.png" />
  </Button>
  <Button Name="btnLogin"
          Click="btnLogin_Click"
          IsDefault="True"
          Width="75"
          Effect="{StaticResource shadowWindow}"
          ToolTipService.ToolTip="Login">
    <Image Source="Images/CheckMarkBlack.png" />
  </Button>
</StackPanel>

There are two special attributes that are set on these buttons. The IsCancel attribute is set to true on the Cancel button. Setting this attribute to true will fire the click event procedure on the Cancel button if the user presses the Escape key. The IsDefault attribute is set to true on the on the Login button. Setting this attribute to true will fire the click event procedure on the Login button if the user presses the Enter key.

Writing the Code for the Login Screen

In each of the click event procedures you will need to close the screen. In the Cancel click event procedure you will set the DialogResult property of the screen to a false value. This will inform the calling procedure that the user clicked on the Cancel button on this screen. In the Login click event procedure you will set the DialogResult property of the screen to a true value. This informs the calling procedure that the user clicked on the Login button and was authenticated. I am leaving it up to you to write the code for authenticating the user. Here is the code for the Cancel event procedure.

private void btnCancel_Click(object sender, RoutedEventArgs e)
{
  DialogResult = false;
}

And, here is the code for the Login event procedure.

private void btnLogin_Click(object sender, RoutedEventArgs e)
{
  // Write code here to authenticate user
  // If authenticated, then set DialogResult=true
  DialogResult = true;
}

Displaying the Login Screen

At some point when your application launches, you will need to display your login screen modally. Below is the code that you would call to display the login form (named frmLogin in my sample application). This code is called from the main application form, and thus the owner of the login screen is set to “this”. You then call the ShowDialog method on the login screen to have this form displayed modally. After the user clicks on one of the two buttons you need to check to see what the DialogResult property was set to. The DialogResult property is a nullable type and thus you first need to check to see if the value has been set.

private void DisplayLoginScreen()
{
  winLogin win = new winLogin();

  win.Owner = this;
  win.ShowDialog();
  if (win.DialogResult.HasValue && win.DialogResult.Value)
    MessageBox.Show("User Logged In");
  else
    this.Close();
}

Summary

Creating a nice looking login screen is fairly simple to do in WPF. Using the DropShadowEffect can add a nice finished look to not only your form, but images and buttons as well. Using a border-less window is a great way to give a custom look to a login screen or splash screen. The DialogResult property on WPF Windows allows you to communicate back to the calling routine what happened on the modal screen. I hope this article gave you some ideas on how to create a login screen in WPF.

NOTE: You can download the sample code for this article by visiting my website at http://www.pdsa.com/downloads. Select "Tips & Tricks", then select "WPF Login Screen 2013" from the drop down list.

Posted: Aug 20 2013, 08:28 AM by psheriff | with 3 comment(s) |
Filed under: , ,
My First Course on Pluralsight
So, my first course went live on Pluralsight today! Entitled "The Many Approaches to XML Processing in .NET Applications" this ~4 hour long video course covers the following topics: - What is this XML Thing Anyway? - A Myriad of Methods to Read XML - 16 Ways to Write XML Documents - Read World Uses of XML - LINQ to XML Step-by-Step - Use XML: An Alternative to SQL If you have ever wanted to work more with XML, then learning LINQ to XML is a great way to do so. This video course will take you step-by-step on the best ways to read and write XML documents. You can check out this course at http://pluralsight.com/training/Courses/TableOfContents/xml-processing-approaches-dotnet-applications Enjoy!
Posted: Jul 23 2013, 01:37 PM by psheriff | with 2 comment(s)
Filed under: , , ,
Creating Collections of Entity Objects using Reflection

In my last blog posts I have been showing you how to create collection of entity objects using code that is custom for each table and object you create. Well, if you use a little reflection code you can shrink this code quite a bit. Yes, we all know that reflection is slow and probably should be avoided in most cases. What I have found out is that loading over 6200 product records into an entity collection still takes less than a second when using Reflection. So, I will leave it up to you to decide which way you wish to go.

We will once again use our Product class that uses nullable types as shown below:

C#
public class Product
{
  public int? ProductId { get; set; }
  public string ProductName { get; set; }
  public DateTime? IntroductionDate { get; set; }
  public decimal? Cost { get; set; }
  public decimal? Price { get; set; }
  public bool? IsDiscontinued { get; set; }   
}

Visual Basic
Public Class Product
  Public Property ProductId() AsNullable(Of Integer)
  Public Property ProductName() As String
  Public Property IntroductionDate() As Nullable(Of DateTime)
  Public Property Cost() As Nullable(Of Decimal)
  Public Property Price() As Nullable(Of Decimal)
  Public Property IsDiscontinued() As Nullable(Of Boolean)
End Class

How Reflection Works

If you wish to set one of the properties on the Product class to a certain value, you write code like the following:

C#
Product entity = new Product();
entity.ProductName = "A New Product";

Visual Basic
Dim entity as New Product()
entity.ProductName = "A New Product"

Sometimes you might want to create a generic routine that you can pass a property name to and the value to set that property to. This can be accomplished using Reflection as shown in the following code:

C#
Product entity = new Product();
typeof(Product).InvokeMember("ProductName",
  BindingFlags.SetProperty,
    Type.DefaultBinder, entity,
     new Object[] { "A New Product" });

Visual Basic
Dim entity as New Product()
GetType(Product).InvokeMember("ProductName", _
   BindingFlags.SetProperty, _
     Type.DefaultBinder, entity, _
        New Object() { "A New Product" })

The InvokeMember is a method of the System.Type class. Using typeof() in C# or GetType() in Visual Basic returns an instance of the Type class which contains meta-data about the Product class. You pass 5 parameters to the InvokeMember method. The first parameter is the name of the property you wish to set. The second parameter is the name of the property or method you wish to invoke; in this case it is the Set property. The third parameter tells InvokeMember that you are using the default binder. The fourth parameter is the variable that contains a reference to an instance of the class specified by the type (in this case the Product object). The last parameter is an object array of whatever you need to pass to the method or property that you are invoking. For setting the ProductName property you only need a single object array of the string you are setting.

A Better Way to Set Property Values

While the InvokeMember method works for setting a property, it is actually quite slow. There is a more efficient way to set a property using reflection. There is a GetProperty method on the Type class you use to retrieve a PropertyInfo object. This PropertyInfo object has a SetValue method that you can use to set the value on that property. Below is an example of calling the SetValue method.

C#
Product entity = new Product();

typeof(Product).GetProperty("ProductName").
  SetValue(entity, "A New Product", null);

MessageBox.Show(entity.ProductName);

Visual Basic
Dim entity As New Product()

GetType(Product).GetProperty("ProductName"). _
  SetValue(entity, "A New Product", Nothing)

MessageBox.Show(entity.ProductName)

The above code is actually a little easier to understand than using the InvokeMember and is over 100% faster! That is a big difference and you should take advantage of it!

Apply Reflection to Loading Collections

When you wish to load a collection of entity classes you will loop through either a DataReader or a DataTable. Before you loop through, however, you should gather a collection of all properties on your Product class into an array of PropertyInfo objects. This way you only get the properties one time instead of each time through the rows you get a single property using the GetProperty method. In the code shown below you will use the GetProperties method to retrieve this array.

You will then build the data reader and move through each row of the data reader by using the Read method. For each row you will now loop through the PropertyInfo array and use the property name to retrieve the corresponding column in the data reader. Remember, this assumes that your column names are the same name as your entity class.

C#
public List<Product> GetProducts()
{
  SqlCommand cmd = null;
  List<Product> ret = new List<Product>();
  Product entity = null;

  // Get all the properties in Entity Class
  PropertyInfo[] props = typeof(Product).GetProperties();

  cmd = new SqlCommand("SELECT * FROM Product");
  using (cmd.Connection = new
          SqlConnection(AppSettings.Instance.ConnectString))
  {
    cmd.Connection.Open();
    using (var rdr = cmd.ExecuteReader())
    {
      while (rdr.Read())
      {
        // Create new instance of Product Class
        entity = new Product();

        // Set all properties from the column names
        // NOTE: This assumes your column names are the
        //       same name as your class property names
        foreach (PropertyInfo col in props)
        {
          if (rdr[col.Name].Equals(DBNull.Value))
            col.SetValue(entity, null, null);
          else
            col.SetValue(entity, rdr[col.Name], null);
        }

        ret.Add(entity);
      }
    }
  }

  return ret;
}

Visual Basic
Public Function GetProducts() As List(Of Product)
  Dim cmd As SqlCommand = Nothing
  Dim ret As New List(Of Product)()
  Dim entity As Product = Nothing

  ' Get all the properties in Entity Class
  Dim props As PropertyInfo() = _
      GetType(Product).GetProperties()

  cmd = New SqlCommand("SELECT * FROM Product")
  Using cnn = New _
          SqlConnection(AppSettings.Instance.ConnectString)
    cmd.Connection = cnn
    cmd.Connection.Open()
    Using rdr = cmd.ExecuteReader()
      While rdr.Read()
        ' Create new instance of Product Class
        entity = New Product()

        ' Set all properties from the column names
        ' NOTE: This assumes your column names are the
        '       same name as your class property names
        For Each col As PropertyInfo In props
          If rdr(col.Name).Equals(DBNull.Value) Then
            col.SetValue(entity, Nothing, Nothing)
          Else
            col.SetValue(entity, rdr(col.Name), Nothing)
          End If
        Next

        ret.Add(entity)
      End While
    End Using
  End Using

  Return ret
End Function

Create Generic Base Class

Instead of writing all of the above code for each entity collection class you need to load, you can create a base class with a generic method that will build your collection for you. Create a class called ManagerBase to which you will create a method called BuildCollection. This BuildCollection method will allow you to specify the type of entity, symbolized by <T>, that you wish to create a collection of. Pass into this method the type of the entity and a SqlDataReader and this method will take care of the rest. With the entity Type you pass in this method can retrieve the array of PropertyInfo objects from that type. A loop is made through the data reader and a new instance of the entity is created using the Activator class’ CreateInstance method. All the properties in the array of PropertyInfo objects is looped through to gather the data into the entity. Each entity is finally added to a generic List<T> collection. When all records have been processed the generic list is returned.

C#
public class ManagerBase
{
  public List<T> BuildCollection<T>(Type typ,
     SqlDataReader rdr)
  {
    List<T> ret = new List<T>();
    T entity;

    // Get all the properties in Entity Class
    PropertyInfo[] props = typ.GetProperties();

    while (rdr.Read())
    {
      // Create new instance of Entity
      entity = Activator.CreateInstance<T>();

      // Set all properties from the column names
      // NOTE: This assumes your column names are the
      //       same name as your class property names
      foreach (PropertyInfo col in props)
      {
        if (rdr[col.Name].Equals(DBNull.Value))
          col.SetValue(entity, null, null);
        else
          col.SetValue(entity, rdr[col.Name], null);
      }

      ret.Add(entity);
    }

    return ret;
  }
}

Visual Basic
Public Class ManagerBase
  Public Function BuildCollection(Of T)(typ As Type, _
    rdr As SqlDataReader) As List(Of T)
    Dim ret As New List(Of T)()
    Dim entity As T

    ' Get all the properties in Entity Class
    Dim props As PropertyInfo() = typ.GetProperties()

    While rdr.Read()
      ' Create new instance of Entity
      entity = Activator.CreateInstance(Of T)()

      ' Set all properties from the column names
      ' NOTE: This assumes your column names are the
      '       same name as your class property names
      For Each col As PropertyInfo In props
        If rdr(col.Name).Equals(DBNull.Value) Then
          col.SetValue(entity, Nothing, Nothing)
        Else
          col.SetValue(entity, rdr(col.Name), Nothing)
        End If
      Next

      ret.Add(entity)
    End While

    Return ret
  End Function
End Class

Use Base Class

To use this base class you will create your ProductManager class that inherits from this ManagerBase class. You can rewrite the GetProducts method shown above with the code shown below. You can see that this significantly reduces the amount of code you need to write.

C#
public class ProductManager : ManagerBase
{
  public List<Product> GetProducts()
  {
    SqlCommand cmd = null;
    List<Product> ret = null;

    cmd = new SqlCommand("SELECT * FROM Product");
    using (cmd.Connection = new
            SqlConnection(AppSettings.Instance.ConnectString))
    {
      cmd.Connection.Open();
      using (var rdr = cmd.ExecuteReader())
      {
        // Build Collection of Entity Objets using Reflection
        ret = BuildCollection<Product>(typeof(Product), rdr);
      }
    }

    return ret;
  }
}

Visual Basic
Public Class ProductManager
  Inherits ManagerBase

  Public Function GetProducts() As List(Of Product)
    Dim cmd As SqlCommand = Nothing
    Dim ret As List(Of Product) = Nothing

    cmd = New SqlCommand("SELECT * FROM Product")
    Using cnn = New _
       SqlConnection(AppSettings.Instance.ConnectString)
      cmd.Connection = cnn
      cmd.Connection.Open()
      Using rdr = cmd.ExecuteReader()

        ' Build Collection of Entity Objets using Reflection
        ret = BuildCollection(Of Product)( _
                  GetType(Product), rdr)

      End Using
    End Using

    Return ret
  End Function
End Class

Summary

In this blog post you learned how to use reflection to fill a collection of entity objects. There are two different methods of setting properties using Reflection. You should use the SetValue method instead of the InvokeMember as it is more efficient. Creating a base class and using a generic method will eliminate a lot of repetitive code.

NOTE: You can download the sample code for this article by visiting my website at http://www.pdsa.com/downloads. Select “Tips & Tricks”, then select “Creating Collections of Entities using Reflection” from the drop down list.

Join PDSA at DevIntersection Conference - April 8 - 11, 2013

Use the Code 'PDSA' when registering and receive $50 off your registration!

Top Microsoft Speakers Featured at DevIntersection & SQLIntersection, Including 3 Speakers from PDSA, Inc.

Top Microsoft and third-party speakers, including PDSA's Paul Sheriff, Michael Krasowski and John Kuhn, will be featured at the April DevIntersection & SQLIntersection conference, April 8-11, 2013 at the MGM Grand in Las Vegas. Look on the website to see the many sessions and workshops, plus save big with our Show Package and Complete Package pricing, and get a workshop, the conference, and a Surface with Windows RT bundled for a great deal.

Contact Us

Web: www.devintersection.com www.sqlintersection.com

Phone: 203-264-8220

Email: info@devintersection.com

Choose a Package Deal, Receive a Surface with Windows RT

Be part of the new crowd that is exploring Windows 8! If you are a SQL Server or .NET developer who will be faced with jumping into Windows 8 in the next year, have we got a great deal for you. The April 2013 SQLIntersection & DevIntersection Conference will offer two package deals that include attending three days of sessions in any track at the conference plus a Surface with Windows RT OR a $300 gift card. And we'll include one or two full-day workshops depending on which deal you choose. Sign up for SQLIntersection / DevIntersection Conference and start to explore the Windows 8 platform that businesses will use over the next decade.

DevIntersection Brochure Is Now Online

If you've been waiting for a copy of the DevIntersection brochure to show your supervisor or training coordinator, the wait is over. You can download it now. We invite you to compare our show to the competition. We have more speakers, more sessions, a better package deal, plus exciting giveaways and evening events.

As a friend of PDSA you can save $50 on DevIntersection / SQLIntersection registration. Use the Discount Code PDSA on the DevIntersection / SQLIntersection registration page.

Posted: Mar 04 2013, 09:07 AM by psheriff | with no comments
Filed under: ,
More Posts Next page »