Configuring for a Setup Project

Eventually, it comes time to transfer your project to the production or quality assurance (QA) computer. In theory, you should just need to copy some files to the other computer. In practice, it's a lot safer to create a setup project that packages up everything you need and unpackages it on the other computer.

You do want to rebuild your setup project every time you're going to release your application; you don't need to rebuild your setup project every time you build your application. The difference between when you need to rebuild your setup project and when you don't comes down to your compile mode: Are you compiling in release mode or debug mode?

When you're working on your application, you want to compile in debug mode so that you can step through your code; when you're ready to release your application (even if it's just to the QA computer), you'll want to compile in release mode so that you get all the optimizations possible. It's only in release mode that you'll need to rebuild your setup project.

You can get Visual Studio to take care of this for you: Go to Visual Studio's Build menu and select the Configuration Manager choice. In the upper left hand corner of the resulting dialog, you'll see a dropdown list set to Debug. This indicates that the settings being displayed are the ones applied during a debug compile. Find your setup project in the list in the bottom part of the dialog and uncheck the checkbox in the Build column (you should also pick a setting for how your setup project is to be built in the Configuration column).

With your Debug settings in place, switch the dropdown list from Debug to Release. After this change, make sure that the Build option for your setup project is checked (you could also uncheck the Build option for your test project because you probably don't need to rebuild it for a release mode compile). With your release mode settings made, click the Close button to save your changes and you're done.

From now on, you just have to remember to switch the dropdown list in Visual Studio's toolbar from Debug to Release when you need a new version of your setup project (and switch the list back to Debug immediately after you generate the setup project so that you get debugging support in your compiles).

Posted by Peter Vogel on 03/19/2015 at 9:26 AM0 comments


Omitting and Including Debug Code

I'm working on an application that allows users to retrieve and then filter/sort their data. The rules for filtering the data seem especially bizarre to me (there are actually two sets of filters) and the users keep piling on requirements.

Since I'm modifying existing code (and don't want to take the time to rip it all out and start over again) I've been including some code to print out useful information to the Output window that helps me debug problems. I don't want this code to go into production, of course, because it would slow the application down microscopically.

I've also got to test how this whole application works based on the security of the particular user. The application determines what security to apply by reading my Windows logon Id and then validating that against a table of users. Changing my security settings would require me to log off and log back on as another user every time I wanted to run through a set of tests. To simplify testing, therefore, I've put in a backdoor that lets me arbitrarily set my security level. I really don't want that code to make it into production.

The Conditional attribute is what saves my Canadian bacon here. I simply include my offending code in a method and mark it with the Conditional attribute. I pass the Conditional attribute some test that checks a compiler variable to see if the method should be included. This example checks to see if a constant called DEBUG is present:

<Conditional(DEBUG)>
Public Sub AssignSecurity

End Sub

I use the DEBUG constant because it's automatically included by Visual Studio when you're compiling in debug mode…and automatically excluded when you compile in release mode (though you can override that).

As you can imagine, I still worry that my security bypass code will make it into production. To help ensure that it doesn't, I have another method, that puts a big red "IN TEST MODE, NOT SECURE" message on the title screen when I'm running in non-secure mode. In addition, before arbitrarily setting the security settings, my code looks for a digitally encrypted key only installed on my development machine. I still worry ... but I can live with that.

Posted by Peter Vogel on 03/11/2015 at 9:02 AM0 comments


Visual Studio in Full-Screen Mode

Even after you maximize Visual Studio's window you don't yet have the maximum space for working with code and the Visual Studio's visual designers. To get the maximum bit of screen real estate available, you can put your Visual Studio edit window in full-screen mode by selecting View | Full screen (or just pressing Shift+Alt+Enter). Full screen mode gets rid of the toolbars and all of your tool windows (Solution Explorer, the Toolbox, etc.); you get to keep the menu bar and the tabs for your open files (though the tabs' appearance is altered to take up less room).

When you need to get out of full-screen mode, all you have to do is click the Full Screen choice that gets added to the menu bar when you enter full screen mode.

You can still display any of the tool windows you want by selecting them from the View menu. You might also want to try memorizing the hot keys that bring up those windows, but those hot key aren't particularly obvious. It helps that the hot keys for the tool windows all begin with Control+Alt. But, unfortunately, Control+Alt+S doesn't bring up Solution Explorer as you might expect. Instead, Control+Alt+S brings up Server Explorer. To get to the Solution Explorer window, you need to use Control+Alt+L (and, no, I have no idea why). Getting to the toolbox is the equally unobvious Control+Alt+X. If there's a shortcut for Test Explorer, I haven't found it yet.

It's not my fault.

But if you're going to bang in a lot of code, it's hard to beat having all that screen real estate. If the hotkeys for the tool windows were more obvious, I'd like it even better.

Posted by Peter Vogel on 03/05/2015 at 10:56 AM0 comments


Leveraging Views in Entity Framework

A typical screen in your user interface probably combines data from several different tables. To handle that, I typically have my back-end processes generate Data Transfer Objects (DTOs) which combine data from several different tables. To load these DTOs with the data they need, I retrieve rows from multiple tables and pull selected columns from each table to populate the properties on my DTOs.

A reader recently pointed out to me that I could drastically simplify that retrieval code by leveraging SQL views. A SQL view pulls together multiple tables (and selected columns from those tables) into a single package. The key feature of a SQL view is that both SQL Server and Entity Framework have a great deal of difficulty in telling the difference between a view and a table.

The major difference between views and tables is that views are read-only: you can't use them to add, update, or delete rows. However, that's less of a problem than you might think, especially in Web based applications.

In an ASP.NET MVC application, for example, my code that retrieves the data to build the DTO will go in a Get method; The code to do the deletes and updates will go in Delete or Post method. While I need to retrieve data from all of the tables to build my DTO often, in my update/delete methods, I only need to work with a subset of those tables (none of the lookup tables, for example, and only those tables that the user changed). In other words, my Get and Delete/Post methods look very different, anyway.

It makes sense, therefore, to create views in SQL Server that correspond to the DTOs I will return from my back-end server. With those views in place, in my Get methods I can retrieve rows through the view with a single trip to the database. This strategy also allows SQL Server do some optimization on the retrieval which isn't possible if I retrieve the tables individually.

In Entity Framework you add a View to your DbContext object with the same code you use to add a table. This example adds a view named MySQLView to a DbContext:

Public Class AdventureWorksLTEntities 
      Inherits DbContext 
    Public Property MySQLView As DbSet(of MySQLView) 
End Class
The code to process a View is identical to the code you'd use to process a Table. You can even update the properties on View, but your code will throw an exception when you call the SaveChanges method (the message is distinctly unhelpful: It says that you can't change the property because it's part of the entity's key).

Posted by Peter Vogel on 02/25/2015 at 2:37 PM0 comments


Handle Conflicting Namespaces with Aliases

Every once in a long while, I have a class name that appears in two different namespaces (there are other kinds of namespace confusions that I can run into but this is most common).

If I use ConfigurationManager, for example, the compiler insists that I either qualify the class name with the namespace (as Configuration.ConfigurationManager) or qualify a bunch of other ConfigurationManager classes with their namespace. I end up with this code:

  Configuration.ConfigurationManager.ConnectionStrings(...

But taking the namespace onto the class name is just the most obvious way to do this is to tack the whole namespace onto the front of the class name. If I'm only use the class once, that's not a problem ... but if I have to repeatedly type in the namespace-plus-class-name, things get very boring very fast.

If you find yourself in that spot, you can assign your namespace a short alias and use it instead the namespace. Here's what assigning an alias looks like in Visual Basic:

Imports sc = System.Configuration;

And in C#:

Using sc = System.Configuration;

Now, you can use your alias wherever you had to type in the namespace to save yourself some typing. My code could now look like this:

sc.ConfigurationManager.ConnectionStrings(...

I hope that clears things up a bit.

Posted by Peter Vogel on 02/18/2015 at 9:28 AM0 comments


Simple ForEach Processing on Lists

If you want to process all the items in a list, you can write a For…Each loop…or you can just call the List's ForEach method and pass it a lambda expression containing the processing you want. This code, for example, sets the OrderStatus property on a list of StatusChange objects to Ordered:

  Dim statuses As New List(Of StatusChange)
  statuses.Add(New StatusChange)
  statuses.Add(New StatusChange)
  statuses.ForEach(Function(s) s.OrderStatus = "Ordered") 

The ForEach method a nice feature. It's a shame more collections don't have it.

Posted by Peter Vogel on 02/16/2015 at 10:13 AM0 comments


Cut or Copy in One Keystroke

This could have been the simplest tip I've ever written: In Visual Studio, if you just want to cut or copy one line, you don't have to select the line. All you have to do is put your cursor on the line and press Control+X or Control+C. Visual Studio will cut or copy the whole line, including the carriage return.

Here's why this isn't the simplest tip I've ever written: There's a downside to this feature. In any other application you must select something before cutting or copying. If you haven't selected anything and accidentally press Ctrl+X or Ctrl+C then nothing happens. Critically, this means that an accidental cut or copy won't cause you to lose what's on the clipboard: No harm, no foul.

That's not what happens in Visual Studio: Visual Studio will always cut or copy something when you press Ctrl+X or Ctrl+C (even if you're on a blank line, Visual Studio will cut or copy the carriage return for the line). This means that if you do an inadvertent cut or copy then you're going to lose whatever you had on the clipboard. When you do make an inadvertent cut or copy and lose what's on the clipboard, you can get back to it by using Shift+Ctrl+V when you paste (the subject of an earlier tip).

You can't completely turn this feature off but you can ameliorate the impact of the inadvertant cut or copy by telling Visual Studio not to cut or copy blank lines. Go to Tools | Options | Text Editor| All Languages and uncheck "Apply Cut or Copy commands to blank lines when there is no selection."

Posted by Peter Vogel on 02/12/2015 at 10:09 AM0 comments


Fill a String with Characters

Sometimes you need a string that's filled with a specific number of characters. There are lots of ways to do that but the easiest is to use the New keyword with the String class because the New keyword gives you access to the String object's constructors.

In fact, the String class has three constructors. The first one initializes the string with whatever you pass to the constructor. This one initializes the string to four equals signs:

  x = New String("====")

Of course, that's not much of an improvement over what you'd do normally:

  X = "===="

But the second constructor is more useful because it accepts a character, an integer and then repeats the character the number of times specified by the integer. This example initializes the string with however may equals signs are specified by initCount:

  x = New String("=", initCount)

The third constructor is the most interesting, though I doubt that I'll ever use it. The third constructor lets you initialize the string with a set of characters from a Char array beginning at some point in the array and for some number of characters. This example initializes the string with the digits from 123456789, starting at the position specified in initStart and for the length specified in initLength:

  x = New String("123456789", initStart, initLength)

If initStart was set to 2 and initLength was set to 4 then x would be set to "3456".

Posted by Peter Vogel on 02/09/2015 at 7:44 PM0 comments


Support Remote Clients with a Custom Exception Object

The custom Exception class I described in a column earlier this month will work fine … as long as the .NET Framework doesn't need to serialize your Exception object to return it to a remote client. If you want to make the extra effort, you can add serialization support to your custom Exception class.

To support serialization you first need to decorate your Exception class with the Serializable attribute. And, if you haven't added any custom properties to your Exception class, that's all you need to do.

But if you do have custom properties on your Exception class then during serialization you must do two things. First, you must override the base Exception object's GetObjectData method. In that method you should call the base version of the method to ensure that the default serialization is performed.

After that, you need to add the values of any custom properties to the SerializationInfo parameter passed to the method, saving the parameters under some name you make up. Here's a version of the method that adds a value called BadOption from a variable in the class to the serialized version of the object:

Private _Option As String
Public Overrides Sub GetObjectData(info As SerializationInfo, 
                                   context As StreamingContext)
  MyBase.GetObjectData(info, context)

  If info IsNot Nothing Then
    info.AddValue("BadOption", Me._option)
  End If

End Sub

You also need to add a constructor that the .NET Framework will call during the deserialization process. In that constructor you need to extract your value from the SerializationInfo, using the name you saved the value under. Once you've retrieved the value you can then update your customer property with it. This example retrieves and updates my BadOption value:

Protected Sub New(SerializationInfo As SerializationInfo,
                  StreamingContext As StreamingContext)
  MyBase.New(SerializationInfo, StreamingContext)

  If SerializationInfo IsNot Nothing Then
    Me._option = SerializationInfo.GetString("BadOption")
  End If

End Sub

Let me know how helpful this is in the comment section, or send me e-mail!

Posted by Peter Vogel on 02/06/2015 at 7:44 PM0 comments


Reformat Your Whole Code File in One Step

Often after I've cut or pasted some text, I find that my code isn't formatted correctly any more. As long as your code is syntactically correct (i.e. no stray brackets or End Ifs without matching Ifs), Visual Studio will reformat your whole file with one key chord: Hold down the Control key and then press K, followed by D.

Boom! Everything looks pretty again.

Posted by Peter Vogel on 01/30/2015 at 10:18 AM0 comments


Control Class ToolTip During Debugging

You're debugging some code and you need to know the value of a string variable. You move your mouse over the variable and -- voila! -- a tooltip appears showing the value of the string.

But, when you think about that, things get complicated. After all, a string has many properties: How did Visual Studio know that the property you're interested in is the value of the string and not, for example, the string's length? And, more importantly, why don't you get that feature with your classes? When you hover the mouse over a variable pointing at one of your classes all that you get is your class' name: Distinctly unhelpful.

You can control what appears in the debugging tooltip in one of two ways. One way is to override your class' ToString method because Visual Studio defaults to calling ToString to generate the debugging message. However, using ToString to support debugging isn't necessarily an option.

For example, I often use ToString to supply the default representation of my class in my user interface (if I add a class to a dropdown list, the list will call my class' ToString method to get some text to display in the list). What I want displayed in my UI and what I want displayed when I'm debugging are often two different things.

There's a better solution for controlling what appears in the debugging tooltip: the DebuggerDisplay attribute. Just decorate your class with the DebuggerDisplay attribute and pass the attribute a string with property names from the class enclosed in curly braces (you can also surround the property names with additional text if you want).

This example will cause the debugging tooltip to display the Address and Type properties from my CustomerAddress class along with some explanatory text:

<DebuggerDisplay("Address={Address},Type={AddressType}")>
Friend Class CustomerAddress
    Public Property Address As String
    Public Property AddressType As String
End Class

Now, isn't that more informative?

Posted by Peter Vogel on 01/26/2015 at 10:26 AM0 comments


Inheriting Interfaces

It's no secret that I love interfaces (I did a whole column about them once). As you add more interfaces to your application you may find that you have several interfaces that look very much alike. These two, for example:

Public Interface ICustomer
    Property Id As Integer
    Property Name As String
    Sub Buy()
End Interface

Public Interface IVendor
    Property Id As Integer
    Property Name As String
    Sub Sell()
End Interface

But, looking at those interfaces, there's obviously the idea of a "business partner" buried in this interface design in the shared Id and Name property. It wouldn't be surprising to find that there are other interfaces in this application that share those Id and Name properties.

You can implement that "business partner" (and simplify maintenance of your application) by defining the business partner interface and then having the ICustomer and IVendor interfaces inherit from it. The result would look like this:

Public Interface IBusinessPartner
    Property Id As Integer
    Property Name As String
End Interface

Public Interface ICustomer
    Inherits IBusinessPartner
    Sub Buy()
End Interface

Public Interface IVendor
    Inherits IBusinessPartner
    Sub Sell()
End Interface

There are lots of benefits to building this inheritance structure: You can now extend both the IVendor and ICustomer interfaces with shared members by adding them to IBusinessPartner. If you ever need to add another "business partner" interface, all the common work is done for you: Your new interface just needs to inherit from IBusinessPartner.

Finally, a variable declared as IBusinessPartner will work with any class that implements ICustomer or IVendor, giving your application more flexibility.

Posted by Peter Vogel on 01/22/2015 at 8:59 AM0 comments


Upcoming Events

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.