Category Archives: ASP.Net

Source Control Considerations for ConnectionStrings in .Net

For .Net projects that have multiple developers, configuration differences can be a real problem. For this post, we’ll use the example of connection strings, but it could just as easily be a directory location, or some other difference. Let’s say that we have two developers, one is using SQL Server, while the other is using SQL Server Express. A minor difference in configuration. The first developer needs to list a DataSource of “.” or “localhost”, while the second developer’s DataSource is something like “.\SqlExpress” or “localhost\SqlExpress”.

Note, for the purposes of this discussion, I’ll refer to some git terminology, as it’s my preferred source control tool, but this could just as easily apply to TFS, subversion, mercurial, etc.

Some developers will put the most common version in their web.config, and the developers in the minority have to change their file without checking in, and regularly undo and redo that process in order to get latest if their are other web.config (or app.config) changes.

To avoid this, some teams don’t check in the web.config file. They check in something like web.config.sample which has the default settings, and you make a local copy called web.config that is not registered with source control. You can make any appropriate changes without causing conflicts. Anytime you get latest and see a web.config change, you’ll want to use your favorite merge tool to pull any necessary changes into your web.config. Less work than the previous version, but more manual merging.

I like to recommend a 3rd method, that uses a lesser known piece of web.config capability. Most config sections allow a configSoure attribute to specify an external config file.

So in the case of the connection string differences, the web.config would get checked into source control, and it’s connection string section would like like the following:

<connectionStrings configSource="connection.config"/>

And then the connection.config file is treated like the second method above. There is a connection.config.sample file in source control that shows all the connection strings you need to have with sample connection info. Like follows:

<?xml version="1.0" encoding="utf-8" ?>
<connectionStrings>
    <add name="SomeDB"
         connectionString="Data Source=.;Initial Catalog=SomeDB;Integrated Security=True;"
         providerName="System.Data.SqlClient" />
</connectionStrings>

Additionally, we have a rake task (could be msbuild, maven, .bat, etc) that helps you initialize the project upon first checkout. One of the things it does, is copy that file from connection.config.sample to connection.config. And our .gitignore file on the project, tells git to ignore connection.config. Now you only need to change your DataSource and are ready to go. And the web.config can change without the need to change your connection.config file. The only time that should change is when you add, remove, or rename a connection string.

This same idea can be used for Elmah config, SMTP config, etc. For example, in development, we have email go to file, and different developers use different directories to store the mail. This scheme handles it.

Lastly, this same scheme can largely handle the differences we have with staging and production environments. Since the differences in web.config from the development branch to the stage and production branch are minimal, merging is pretty painless. And those external config files are a one-time setup on the server.

Consider this pattern for your projects, and let me know what you think. Either in the comments below or at @thoolihan. And if you find any room for improvement or have other feedback, please pass it along.

Expert Business Objects: Read It, Even If You Don’t Need The Framework

I’ve been reading Rocky Lhotka’s Expert C# 2008 Business Objects book. CSLA is a bit of a polarizing framework. A lot of comments on the book are along the lines of “outlived it’s usefulness given the current framework updates” or just generally “not keeping up with modern software trends.” It should also be noted that here are also a lot of positive comments from satisfied framework users.

Here’s what I think so far. The text of the book, not necessarily the framework will change the way I do development. Rocky leverages implements many key interfaces and observes many simple conventions that lead to a smooth experience with objects in any .Net UI paradigm (WPF, Silverlight, Web, WinForms, etc). It’s a case study in all of the things your objects should do to ease databinding and support transactions and multilevel undo. And that says nothing of the way these objects support remote calls (via marshalling or traditional copy by value calls).

True, the framework could stand to get away from singleton methods and other aspects that make unit testing and mocking more difficult. But reading this book, I think most developers and architects with any reusable frameworks of their own will realize just how many opportunities they missed.

Why Clint Eastwood is My Programming Hero

This post has been stewing for a while. I’ve struggled for a way to describe the needless clash I see between the communities I work in. But I think I’ve found my analogy.

Ever watch a Clint Eastwood Western? Not Dirty Harry, or any the modern-setting movies he’s been directing lately, but the Westerns. In particular, the Man With No Name series and The Unforgiven. They were a culture shock when they came out. John Wayne, Roy Rogers, Bananza, etc all dominated the Western story telling. White hats and white horses. There might be a happy end, or a sad end, but the lines of good and evil were drawn, and Justice was a virtue.

It’s a misconception that Clint’s movies were different because he was the bad guy. But he wasn’t. He was an agnostic, or better yet, a mercenary in a world of gray. Rarely in those movies was any character purely good. His character, “the man with no name”, looked at the Civil War and didn’t see right and wrong, but death and corruption. He was brutally honest and indifferent at the same time. He evaluated options and propositions on his own terms, when needed. He took advantage of both sides.

And he clearly saw fault in himself, and everyone else. He recognized there was no innocent, and no perfect. Best embodied by the following line from Unforgiven when the Scofield kid is trying to justify a killing he feels guilty for by claiming “he had it coming.” Clint (Will Munny) responds:

“We all got it coming, kid.”

What’s all this have to do with development? I work in multiple environments. Most commonly .Net and Ruby. I’m reasonably active in the community going to user group meetings and conferences. I’m active on social networks and stackoverflow. And I listen to podcasts. All from both communities.

And I can’t get over the amount of criticism and disdain they have for each other.

What Ruby people say about .Net. Ruby developers talk about the ceremony of .Net. And the flawed use of compiler as a testing tool. And they talk about .Net developers relying on Microsoft for direction and enhancements. And every fictional .Net developer that a Ruby person talks about is over 40, works 9-5 and hasn’t gone to a user group in years.

What .Net people say about Ruby. They build simple commerce sites and blog engines, not enterprise applications (DHH didn’t really help that one with his infamous enterprise slide). Dynamic typing doesn’t work in larger applications. It’s slow. It’s not interoperable. How can you program without an IDE. Carl on .Net Rocks frequently says (or at least use to) that it’s very similar to Visual Basic.

What I think about the .Net community. Like all stereotypes, there are some truths in the fictional .Net developer. There are a lot who do not engage the community outside their workplace. And many developers are too reliant on Microsoft for innovation. And for all of their love of the type system, most .Net developers don’t understand it. One in ten .Net developers I interview correctly answers the “var” is still statically typed. And there are a lot of developers who cling to their architectures, unwilling to look at new patterns and practices. Stored Procedure experts who don’t want to hear with proper object caching and execution plan caching, an ORM can actually be faster than an ADO.Net solution (let alone and ORM using stored procs).

That said, there are a lot developers who care and do apply modern practices in .Net. Want proof? Google any of the following terms: StructureMap, NHibernate, Fluent NHibernate, NUnit, MSpec, SpecFlow, Castle Project, Mono, Ninject, etc. The ASP.Net MVC framework has a ways to go to catch up to Rails in maturity, but the reason it has seen such rapid adoption is that people in the .Net world do move to better tools given the right exposure. And community pressure can make a difference with Microsoft. Note the massive revamps by Microsoft in technologies that were launched badly (ie Entity Framework, Silverlight).

What I think about the Ruby community. While I agree with little of the technical criticism that .Net people have for Ruby, I have a big problem with attitudes and perceptions. As I see it, the Ruby community is currently the most elitist community in technology today. I started working with Ruby in 2005, and have written code generators, rake build, rails sites, a sinatra site and more in Ruby. Yet I regularly go to ruby presentations where the chatter is how .Net developers just aren’t enlightened yet. Apparently I’m part of some unwashed ignorant mass of people they need to save. Ruby and Agile compete for the biggest outbreak of “religion” in the technical community.

And they say .Net devs rely on Microsoft for answers. But these Ruby devs rely on 3 or 4 “Ruby”-gods on twitter to tell them what view engine or testing framework they should be using in their next project. And everyone thinks every piece of code should be a gem that can be used by the world. A recent Ruby Show podcast announced a gem for validating email addresses. So I should create a gem for every regular expression in my project and distribute to the community. Fantastic.

That said, Ruby has a great development story. As with any early adoption, the first people over were ambitious and risk takers. That has benefits. And these were people who cared about their coding, so the conventions, testing patterns, and developer experience are all very nice. They’re IDE agnostic. The documentation comes with it’s own server for hosting it, and it’s in simple HTML. How many vendor products would benefit from that approach?

Back to Clint. So how does this tie back to Mr. Eastwood? It’s frustrates me to see this useless struggle, and the mud-slinging involved. No development platform is perfect or all powerful. And being a member of a certain community doesn’t make you valuable, it’s what you do within that community and how much you learn and teach that says something. I would rather hire the most active and flexible member of the COBOL community, than to hire a programmer in a hip new framework that really has his or her head in the sand.

I’m grateful to work in multiple frameworks and languages. I try to take the best value and patterns from each and apply it to any programming I’m doing. And I don’t get religious or emotional about it. To put it in the man with no names terms, I ride in, take a honest look at myself at those around me, try to produce the most value, and then move along. Without expectation or attachment.

This same dichotomy exists in other forms. Agile vs the world. That would be an interesting post.

In the beginning, community enthusiasm and pride is necessary to get a community going. And early members are well intentioned. But when that turns to religion, zealotry, and segregation, things get ugly. And both communities suffer from that. In other words, we all got it coming.

NHibernate and Auto Properties

I’ve been working through the NHibernate with ASP.NET ProblemDesignSolution (Wrox Blox), with some small changes. I’m writing my sample in C# using the .Net framework 3.5. I prefer to use auto-properties.

It’s common that fields have private setters and only nhibernate can map using the backing field (set via reflection).

public String City { get; private set; }

The problem is telling NHibernate how to find the backing field. When you have an explicit field, you end up with something like:

<property access=”field.camelcase-underscore” name=”City” />

But with no backing field, that is a problem. I started looking around on the net and found the following:

StackOverflow discussion without much good info
and a blog post with an interesting response from Ayende Rahien.

Ayende is saying to not worry about the issue, NHibernate will still be able to set via reflection. That’s fine, but it feels a little “magical”, especially to a new developer coming along.

Why not set protected? It’s not unreasonable to expect a maintaining developer to understand that NHibernate sub-classes your class.

public String City { get; protected set; }

Now the mapping stays simple too:

<property name=”City” />

And there is no need to expect a maintaining developer to know that reflection magic is setting the property.

Handling Persistance in Asp.Net with Dynamic Controls

I worked on a project a couple of years ago using dynamic controls in an Asp.Net WebForms environment. Managing dynamic controls can be a real hassle.

So when I read Dave Reed’s great article about Viewstate, I wondered if I could do it better now. I worked up a simple example using no Viewstate where values persist across postbacks. Going to the page new resets everything.

The one piece I don’t like is that it uses session for a control count. But it’s a single Int32 per user that get’s stored in session, so it could be worse. Anyway, here’s the code…

Note: the aspx page has a placeholder (phOne) and two buttons (btnAdd) and (btnRemove). EnableViewstate is false on phOne.

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Web
{
    public partial class Dynamic : System.Web.UI.Page
    {
        private const string KeyNumControls = "DynamicPage_NumControls";
        private const int DefaultControlCount = 2;

        protected override void OnInit(EventArgs e)
        {
            CreateControls(NumberOfControls);
            base.OnInit(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                CreateControls(DefaultControlCount);
            }
        }

        private void CreateControls(int controlCount)
        {
            NumberOfControls = controlCount;
            while(phOne.Controls.Count > NumberOfControls)
            {
                RemoveLastControl();
            }
            while(phOne.Controls.Count < NumberOfControls)
            {
                CreateControl();
            }
        }

        private void RemoveLastControl()
        {
            phOne.Controls.RemoveAt(phOne.Controls.Count - 1);
        }

        private void CreateControl()
        {
            phOne.Controls.Add(new TextBox { EnableViewState = false });
        }

        protected int NumberOfControls
        {
            get
            {
                Session[KeyNumControls] = Session[KeyNumControls] ?? 
                                        DefaultControlCount;
                return (int)Session[KeyNumControls];
            }
            set { Session[KeyNumControls] = value; }
        }

        protected void BtnAddClick(object sender, EventArgs e)
        {
            NumberOfControls += 1;
            CreateControl();
        }

        protected void BtnRemoveClick(object sender, EventArgs e)
        {
            NumberOfControls -= 1;
            RemoveLastControl();
        }
    }
}