Thoughts from Dan Miser RSS 2.0
 Thursday, November 08, 2007

I've had some conversations with people about the label of ALT.NET. They are of the opinion that it causes controversy by setting up the "elitist" vs. "everyone else" mentality. This is not a new observations (see here and here, e.g.).

I'd like to propose that the divisiveness of the ALT.NET moniker be abolished as quickly as possible. To that end, my proposal for the name is Pragmatic.NET. It's both a state of mind and an homage to the Pragmatic Programmer series that touches on several of the topics important to this group.

Discuss...

Thursday, November 08, 2007 11:54:09 AM (Central Standard Time, UTC-06:00)  #    Comments [2] -
.NET

I'm more than a little disappointed that I missed the ALT.NET conference in Austin, but I'm extremely happy that it looks like the movement has crystallized and gained enough momentum to be a legitimate option for .NET developers. Steve Kronsnoble made an analogy to the Agile Manifesto, where it took a bunch of informal participants and related ideas and turned them into industry standards. Hopefully, when looking back on this event years from now, people will be able to identify this as the genesis of  .NET.

I really like the idea of ALT.NET, and it maps to discussions I've had with many developers about trying to find a "Garden Path" of .NET development. Some percentage of .NET developers will use whatever Microsoft tells them to without question. That's fine, but that's not how I think. I like to grab the best technology no matter where I find it (Open Source, other languages, etc.) . I want to talk about things like NHibernate, Spring.NET, Subsonic, the new ASP.MVC framework, Domain Driven Design, Test Driven Design, Unit Testing, and on and on. To me, that's the excitement of ALT.NET.

To do my part, I'd like to start a discussion on where and when to hold a local Milwaukee version of this OpenSpace conference. If you're passionate about .NET development and want to help shape this new movement in the Milwaukee area, please leave a comment so we can find a way to move the ball forward.

Thursday, November 08, 2007 10:02:04 AM (Central Standard Time, UTC-06:00)  #    Comments [5] -
.NET
 Monday, November 05, 2007
I've been working more with data-binding and the ObjectBindingSource component that I wrote about here. Here is some stripped-down sample code to help investigate more data-binding concepts.
class Customer { 
  int Id;
  BindingList Orders;
}

class Order {
  int OrderNumber;
  Product ProductInfo;
}

class Product {
  string Vendor;
  Product Self;
}
Assume that we want individual GUI components for the Customer object, and a grid to display the associated orders, with the related Product information displayed along with the Order. Here are some quick pseudo-code tips to get things wired up properly.
  • CustomerObjectBindingSource.DataSource = typeof(Customer)
  • CustomerObjectBindingSource.BindableProperties.Add("Orders"). (If you don't do this, the detail ObjectBindingSource won't work later on.)
  • OrdersObjectBindingSource.DataSource = CustomerObjectBindingSource and OrdersObjectBindingSource.DataMember = "Orders"
  • OrdersObjectBindingSource.BindableProperties.Add("Product")
  • DataGridView.DataSource = OrdersObjectBindingSource
  • Modify the DataGridView column for Product by setting:
    • column.DataSource = ProductsBindingSource
    • column.DisplayMember = "Name"
    • column.ValueMember = Self
  • **IMPORTANT** - Use the same object references everywhere for the product objects (i.e. in the DataGridView column and where you access them in your code). In the sample, I use the productBindingSource component for both the lookup in the grid and the way to lookup individual Product instances. Another alternative that I tested is to use a singleton class for the collection. If you don't do this, you will get the dreaded "DataGridViewComboBoxCell value is not valid" error when the grid tries to populate the Product value.

For concrete details, download this project. I look forward to your comments.

Monday, November 05, 2007 11:26:17 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -
.NET
 Tuesday, October 30, 2007
Here are a couple of things to remember when you want to use a parameterized LIKE clause in a SELECT statement.

When using a parameter to an integer ID column, you need to break the statement apart so that the parameter stands apart from the wildcard characters:


string sql = 
  @"SELECT * FROM myTable WHERE iId like '[%]' + @iId + '[%]'";

However, that same syntax will not work if you are using a varchar column. Instead, you need to embed the wildcard characters directly into the paramter's value:


string sql =
  @"SELECT * FROM myTable WHERE vcDesc like @iId";

cmd.Parameters.Add(new SqlParameter("@vcDesc", "%" + desc + "%"));

The second syntax works in both cases, so it probably just makes sense to use that everywhere and not worry

Tuesday, October 30, 2007 2:07:42 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -

 Saturday, October 27, 2007

Subtitle: How to force .NET Grids to respect Object-Oriented designs

Microsoft clearly intended the DataGridView to be used with databases and primitives. With the company inventing .NET making it difficult to write GUIs with a proper domain model, it's no wonder that the majority of .NET code out there is littered with data-access metaphors.

Take the following code (yes, I know there are fields here, but it takes less space):


public class County

{

    public County() {}

    public string name;

    public double taxRate;

}

public class CountyTax

{

    public CountyTax() {}

    public County County;

    public double Amount;

}

There is no way out of the box to get a DataGridView to display and edit the CountyTax object's County and Amount fields. I'd like to have a combo box to display a list of county names, select one, and then enter an amount. Later, I can calculate the tax by multiplying the TaxRate for the selected county and the Amount I entered. In other words, I want to employ good domain design principles.

Here are a couple of solutions, depending on whether or not you want to add extra code to each grid, and use reflection or get some design-time support in a fairly encapsulated solution with faster-than-reflection performance.

I haven't had a chance to check out Orcas, but I can only hope that Microsoft has finally seen the light and will treat object-oriented developers to a fully functioning grid.

Saturday, October 27, 2007 9:59:37 PM (Central Standard Time, UTC-06:00)  #    Comments [1] -
.NET
 Friday, October 26, 2007
I would like to propose a Developer's Hippocratic Oath that would start with: "First, do no harm". ¹ Too often, a developer makes a change to a system that later proves to be disruptive or harmful. Yes, humans will always find a way to introduce bugs into code; however, we can all strive to reduce the impact of those bugs by:
  • Understanding the infrastructure and tooling support, and pledge to make it better by automating more of it. Time spent automating things here reduces the chances of manual error later.
  • Adopting a culture of testing. Unit testing tools are ubiquitous at this point. Even if you can't test everything, you can start by testing something.
  • Fostering a spirit of continuous improvement in both talent and code. Take the time to refactor that code that bothers you. If it bothers you, it bothers someone else. Remember, refactoring requires discipline and unit testing to be complete!
  • Fixing a bug at the source of it's error, rather than applying a band-aid further downstream - regardless of the schedule pressure.

Anything else you care to add before we codify this? :-)

Nitpicker's Corner²

¹Yes, I know that the exact phrase "First, do no harm" is not actually in the Hippocratic oath. However, it is pithy and memorable and serves the purpose and intent perfectly in this context of establishing a new oath for Developers. If we want to vote on just naming it the Misercratic Oath for Software Developers (thanks, Steve!), we could go that way, too.

²With apologies to Raymond Chen.

Friday, October 26, 2007 12:09:03 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -

 Monday, October 22, 2007
Moving from a legacy system, one needs to appropriately deal with bad data in the database. For example, in order to put a primary key on a table, the column(s) in that primary key must be able to uniquely identify one record. If you need to find rows with duplicate entries before adding a primary key, you can start with this query:


select Id
from MyTable
group by Id
having count(*) > 1
Monday, October 22, 2007 1:33:51 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -
ADO.NET
 Friday, October 12, 2007
Here is the target that I used to generate an FxCop report and integrate it seamlessly into the CC.NET web dashboard.

<FxCop
  TargetAssemblies="$(TargetAssembly)"
  RuleLibraries="@(FxCopRuleAssemblies)"
  AnalysisReportFileName="FxCop.xml"
  FailOnError="False"
  ApplyOutXsl="False"
  OutputXslFilename="Vendor\FxCop\Xml\FxCopReport.xsl"
  Verbose="False"
  IncludeSummaryReport="True"
  WorkingDirectory="$(MSBuildProjectDirectory)"
  ToolPath="$(MSBuildProjectDirectory)\Vendor\FxCop"/>

The key here is to be sure that ApplyOutXsl is set to False. If it's set to True, then the output will not get logged into the CC.NET log, which means when the dashboard tries to find it, it won't be there.

The other thing of note here is that I have all of my third-party tools, like FxCop, Sandcastle, Enterprise Library, etc. in a Vendor subdirectory of my project. By doing this, I can pick up the one Vendor folder and get another project up to speed quickly (through copying or Subversion externals).

Friday, October 12, 2007 9:48:36 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
.NET
 Thursday, October 11, 2007

When customizing the appearance of the CC.NET Web Dashboard, you often need to modify the file c:\Program Files\CruiseControl.NET\webdashboard\dashboard.config. However, you won't see the changes you make there reflected back in the browser until that file is reloaded.

The easiest way to reload dashboard.config is to quickly modify web.config (add a space and delete it), and save. This forces IIS to reload the web application, which in turn causes dashboard.config to give up it's new settings. This is especially useful in a hosted environment where you don't have access to administration-level tools.

An alternative would be to just bounce the entire web server by stopping and starting the service, but that's not always feasible nor practical.

Thursday, October 11, 2007 11:58:27 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
.NET
Navigation
Archive
<November 2007>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Dan Miser
Sign In
Statistics
Total Posts: 339
This Year: 5
This Month: 0
This Week: 0
Comments: 618
All Content © 2010, Dan Miser
DasBlog theme 'Business' created by Christoph De Baene (delarou)