Authentication in WinForms (VB versus C#)


I had a fun issue that I finally got to today. I added a kind of security "audit" feature to a VB application the other day. To do it, I had to get the user name. In VB, it was fairly simple:
 
    Private Function GetUser() As String
        Dim userName As String = Thread.CurrentPrincipal.Identity.Name
        If (userName.Contains("")) Then
            Dim broken As String() = userName.Split("".ToCharArray())
            userName = broken(broken.Length – 1)
        End If
        Return userName
    End Function
 
It was my thought that I could simply "copy" and Sharpify the code and have it work. It would look like this:
 
        private string GetUser()
        {
            string userName = Thread.CurrentPrincipal.Identity.Name;
            if (userName.Contains("\"))
            {
                string[] broken = userName.Split("
\".ToCharArray());
                userName = broken[broken.Length – 1];

            }
            return userName;
        }
 
No dice. I get String.Empty for the user name, as Thread.CurrentPrincipal is a null object. I tried the properties of the application first and found the property pages are completely different. I then tried examining the files in the project, but could not easily figure out the proper file to dink with. Since I am lazy, I looked up the Identy object and after a drill, I find this solution (change to code highlighted):
 
        private string GetUser()
        {
            string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
            if (userName.Contains("\"))
            {
                string[] broken = userName.Split("
\".ToCharArray());
                userName = broken[broken.Length – 1];
            }
            return userName;
        }
 
Now everything is working as expected.
 
Peace and Grace,
Greg
Advertisements

We need to rethink application architecture


I was answering a question on architecture this morning in which the person was asking how to lay out an application. There were three things that hit me and they are three things I see often in development.
  1. The poster seemeed to feel that small applications are best set up as monoliths, with all of the code in the ASP.NET application, while big applications should be tiered.
  2. The poster seemed to feel that you can either develop applications from the bottom up or top down.
  3. The poster was highly focus on the fact he was developing an "ASP.NET Application"

All of these are mistakes, in my opinion.

Application Labeling and Development

First, let’s look at how we label applications. I often hear people say, I am building a windows forms application, or I am building a WPF application, or even I am building a back end application. This is just plain wrong. You are not building an X application. You are building an application to solve a business problem. You are using ASP.NET for your user interface, or presentation, tier, but the application is not defined by the UI technology, or at least it should not be.

This type of thinking is why we end up completely rewriting our code when we add a new UI technology. We also brand applications by UI, so we have MyApp and MyApp Web or visa versa. And we treat the web app and windows apps as two separate apps, even though they are solving the same problem.

Tiering, or layering, applications is not new. Microsoft pushed this concept heavily in the COM world, even labeling it Distributed Network Architecture, or DNA. ANd, in the COM world, some people actually got it. The worm has turned, however, and many of the .NET technologies are not conducive to tiered architecture. The original 2.0 DataSet model illustrates this. And, since it is easier to leave the TableAdapters in the data object project, we find many people leaving it that way.

Microsoft is trying to separate concerns with technology, but you cannot force out bad process with technology. The original ASP.NET model was designed to separate code from UI, but the code behind classes were still UI and developers still loaded them with business logic, often without dividing the work into routines that could be refactored to tiers. With WPF and Silverlight, they took this a step farther, but there are still people putting business logic into WPF/Silverlight libraries, controls, etc. ASP.NET MVC takes this one step farther by making the ASPX classes, or views, "stupid". You cannot write much code in a view and it is hard to write code that is not UI related in the view. But, you can still load up your controller with lots of business and data logic, so they have not really solved the problem; they have just forced the errant developer to move the code on class lower on the food chain. It is still mixing business/data logic with the UI tier/layer.

The problem is exacerbated by the samples out on the web. Take, for example, the following code from a prominent member of the ASP.NET MVC team:

namespace MvcApplication5.Controllers
{
  public class ProductsController : Controller
  {
    NorthwindDataContext northwind = new NorthwindDataContext();

    [ControllerAction]
    public void Create(string ProductName, int CategoryID, int SupplierID, double UnitPrice)
    {
      Product product = new Product();
      product.ProductName = ProductName;
      product.CategoryID = CategoryID;
      product.SupplierID = SupplierID;
      product.UnitPrice = UnitPrice;

      northwind.AddProduce(product);
      northwind.SubmitChanges();

      RedirectToAction(new { Action = "Category", ID = product.CategoryID });
    }
  }
}

I am not here to dink the sample, as I feel samples teach concepts and not necessarily architecture. I also have great respect for the person who posted the code and have seen other examples of his work that do not blur the lines. The problem is not the sample, but what the developers reading the sample do. Seeing this in a blog entry, they assume this is a proper pattern.

Notice what happens here. If I build my entire ASP.NET MVC application in this manner and my boss states that he wants a WPF version of the app (or windows forms), I have to rewrite the entire application, as my data access (LINQ) is set up in my controller. Not a good way to build applications. Fine for samples, but bad for applications.

If this were an isolated incident and only related to samples, I would skip the entire thought process. But, I see this all the time. There are a couple of reasons for this:

  1. Few people are releasing books and articles to shift this way of thinking – and it is a paradigm shift. When the trainers are not teaching it, the masses will not learn.
  2. The drag and drop tools are set up, at least initially, where they blur the lines and do a bad job of separating concerns. And when they add bits that separate concerns, like the bits that divide the TableAdapter from the DataSet, it is not the default.
  3. There is a misconception that it costs lots of time to tier/layer an application.

Item #3 is somewhat true, but much of the time is only eaten the first time, as there is a learning curve. After the curve is crossed, the developer no longer needs to eat from that trough every time. There is still a bit of overhead, but it is more overhead in defining what you are building, which you SHOULD be doing anyway. It may also be overhead in writing tests and other code quality practices, but that is a story for another post.

I am working on a book right now, with no publisher yet. It is focused on properly tiering applications and I am focusing it on Visual Studio 2010. That will help with item #1, but we need more people doing this to turn the tide.

I cannot do anything about item #2 and neither can most of you. The only thing we can do is give feedback to the folks developing the tools and teach people how to overcome drag and drop as a liability.

Development Style

Tiering applications is not enough. The other practice we need to get to is defining applications in light of business. Business drives development; development does not drive business. I know this is an ideal that is not often met, but it should be.

I am all for Agile methodologies, as I see they are the best way to respond to changing business needs. I am against the concept that Agile and requirements do not mix. I don’t mind thinning down requirements, but an application without requirements is an application doomed to fail.

At minimum, I feel you need to have a good set of use cases. Properly done, the use cases describe the business process involved and do not get heavily into technology. Business people should not be designing databases or applications. Leave that to the developers. But, you should have a firm understanding of what is being accomplished before you start coding.

With a good set of use cases, you can more easily divide into teams and get everyone started from day one. The tester can start developing tests, even though he cannot fill them in. The technical writer can start writing manuals and help files, although he cannot get into firm specifics. And, if you take a bit more time to develop the contracts between layers, you can get UI, data and business developers rolling in parallel, not serial. This is powerful and greatly speeds up development. It also forces closer collaboration and communication, when done correctly. Yes, you will have some refactoring in each team, so the efficiency is not aboslutely perfect, but I have never seen optimal development. Remember: Even car engines lose most of the power created by combustion – there is no such thing as 100% efficiency.

If there is one take away, you must understand the process before you can properly build a tool for that process.

Small Versus Large

This one galls me. Perhaps even more than the other two points. Good architecture is good architecture.

Sure, you might take some shortcuts to bang together a quick prototype, but if management sees the prototype as a finished work, you are never going to find the time to refactor it the way it should be. And, once you get the mindset, it does not take that much time to divide the work into libraries and have a UI that is just a facade. As mentioned, you have to change your thinking.

One of the easiest ways to change your thinking is to adopt a Test Driven mindset. Unlike purists, I do not believe you have to always write tests first, although it is the best way. You do have to write them early and make sure you are testing the majority, if not all, of your code. There is a small amount of time taken in writing tests, but some of your tests will be generated once tools like PEX hit the mainstream, so you do not need to hand code to 100% code coverage.

How does TDD help you make your UI a facade instead of an interface with business logic? Simple. UIs are hard to test. This will change in the future, as well, so those of us training people have to hit the bricks before the tools are readily available to test app logic in a UI. After that hurdle is crossed completely, we will be fighting a losing battle.

The point here is small apps need proper architecture, just like large apps. You might shortcut a short lived app, but so many short lived apps become mission critical, so be careful here. You might also shortcut with a prototype, but make sure the owners understand it is a prototype or you will have to live with the mush you just created.

Summmary

What I am stating in this blog entry is an application is not a UI. Applications are code modules that solve business problems. The method of interacting with them is a faceplate. If you get this one item down, you will find you stop thinking "which is bettter? top down or bottom up?". You will also stop calling your apps "ASP.NET app" and "WPF app". And, you will stop thinking you can shortcut small apps. The last is perhaps the most important, as you develop habits when you code. Too many "small" apps and you will develop some pretty decent bad habits.

Have fun coding.

Peace and Grace,
Greg

Windows 7 Line Up Announced


If you have not kept up, Microsoft released some information about Windows 7 about 1 hour ago. There are going to be six SKUs for Windows 7:
 
  • Windows 7 Starter
  • Windows 7 Home Basic (emerging markets only)
  • Windows 7 Home Premium – suggested for home users
  • Windows 7 Professional
  • Windows 7 Enterprise – Business premium SKU
  • Windows 7 Ultimate – A mixture of Home Premium and Enterprise (see below)

Here is the MS information about the SKUs:

Windows 7 Starter

Windows 7 Home Basic

(emerging market only)

Windows 7 Home Premium

Windows 7 Professional

Windows 7 Enterprise and Ultimate

Key Feature list

·          Broad app and device compatibility with up to 3 concurrent applications

·          Safe, reliable, and supported

·          Ability to join a Home Group

·          Improved taskbar and JumpLists

·          Starter features

·          Unlimited applications

 

·          Live Thumbnail Previews & enhanced visual experience

·          Advanced networking support (ad-hoc wireless networks and internet connection sharing)

·          Mobility Center

·          Home Basic features

·          Unlimited applications

 

·          Aero Glass & advanced windows navigation

·          Easy networking & sharing across all your PCs & devices

·          Improved media format support, enhancements to Windows Media Center and media streaming, including Play To

·          Multi-touch and improved handwriting recognition

 

·          Professional features

·          Unlimited applications

 

·          Ability to join a managed network with Domain Join

·          Protect  data with advanced network backup and Encrypting File System

·          Print to the right printer at home or work with Location Aware Printing

 

·          Professional and Consumer

·          Unlimited applications

 

·          BitLocker data protection on internal and external drives

·          DirectAccess provides seamless connectivity to your corporate network.  (requires Windows Server 2008 R2)

·          Decrease time branch office workers wait to open file across the network with BranchCache. (requires Windows Server 2008 R2)

·          Prevent unauthorized software from running with AppLocker

Note: Ultimate includes all Enterprise and all Home Premium features, including multi-language packs.

– Windows 7 Enterprise is available only through Microsoft Volume Licensing

Peace and Grace,
Greg