About Models

In this set of posts when I talk about model I mean the Model component of Model View Controller.

Recently I have been working on a Model/Business Rule engine.

A lost of people that implement MVC or MVP tend to use the Model component as a simple data container with methods.  This does not keep the model as powerful or flexable as possible.

The Model can be used to validate a set of data.  For example we have a utility (in about 20 lines of code) that loops through our database and reports all of the validation faliures.

In order to validate data the model must be able to be populated with invalid data (or null data).  This means thatlanguage type systems are not sufficient.  We developed our own abstract type system in which any type can be supplied a string value. Integers set to XXX are not valid, but at least the model can report this.

Our model forms a tree of composite objects. Business rules are attached to these objects.  The composite supports XPath querying so that our business rules can be robust with respect to changes in the model structure.  We implemented an XPathNavigator descendant to provide this functionality.  Our composite objects have “attributes” (not in the C# sense of [XXXAttribute])  that use our model types.

How to view WMI queries in a dataset.

The following sample code demonstrates putting WMI WQL queries into a DataSet and displaying it in a datagridview.

This could become the basis of a really powerful system management utility. 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Management;

namespace WMIForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            WMIQuery(“SELECT * FROM Win32_Service”);           
        }

        private void WMIQuery(string query)
        {
            SelectQuery qry = new SelectQuery(query);

            DataSet ds = new DataSet();
            DataTable Table = ds.Tables.Add(“WMI”);

            ManagementObjectSearcher ms = new ManagementObjectSearcher(qry);
            ManagementObjectCollection mc = ms.Get();

            Boolean loaded = false;

            foreach (ManagementObject mo in ms.Get())
            {
                if (!loaded)
                {
                    foreach (PropertyData prop in mo.Properties)
                    {
                        Table.Columns.Add(prop.Name);
                    }
                    loaded = true;
                }
                DataRow row = Table.NewRow();
                foreach (PropertyData prop in mo.Properties)
                {
                    row[prop.Name] = prop.Value;
                }
                Table.Rows.Add(row);
            }

            dataGridView1.DataSource = Table;
        }

        private void GoButton_Click(object sender, EventArgs e)
        {
            WMIQuery(QueryTextBox.Text);
        }
    }
}

Lightweight Maintenance Screens

The following can easily be turned into a lightweight maintenance screen:

        private void Form1_Load(object sender, EventArgs e)
        {
            _Conn = new SqlConnection(“My Connection String”);
            _Adapter = new SqlDataAdapter();
            _Adapter.SelectCommand = new SqlCommand(“execute wsp_my_select_all”, _Conn);
            _Builder = new SqlCommandBuilder(_Adapter);
            _DS = new DataSet();
            _Adapter.Fill(_DS);
            dataGridView1.DataSource = _DS.Tables[0];
            dataGridView1.Columns[0].Visible = false;
            dataGridView1.Columns[“rowversion”].Visible = false;   
        }

        private void SaveBtnClick(object sender, EventArgs e)
        {
            //Do something useful with any exceptions here
            _Adapter.Update(_DS, _DS.Tables[0].TableName);
        }

What Dot Net Rocks Does Not Get About The GPL

In a number of recent Dot Net Rocks shows Carl Franklin has mentioned that Microsoft is not anti-open source, just anti-GPL. From his comments it appears that Carl does not understand that a given piece of code may be released under a number of licences.

The GPL is based upon copyright law.  By default you may not use someone else’s copyrighted code without permission.

With a commercial licence you are paid for the right to use the code. That is the price, if the price is too high don’t use the code.

GPL code is released on the condition that it is only built into an application or dll that only consists of GPL code or GPL compatible code.  This is the price of using GPL code. If the price is too high don’t use the code.

If you modify GPL code you only need supply the changed source (under the GPL) to the person you give the application to and only if they ask.  Some people do more and publish publicly but that is not part of the GPL.

There is no reason that a given piece of code cannot be released under multiple licences.  If you own the copyright you can sell the code commercially and release the code under the GPL. 

When To Branch in Version Control

When you are developing a product that has a live version, yet you wish to perform enhancements to the application.  How do you cope with the version control (you do use version control…) of fixes or enhancement to the live version.

The solution here is to use a branch.  The branch must be from the labelled point (you do label/checkpoint builds) used for the live build.  The trick is to keep the branches as small as possible and keeping as few maintained. It adds complexity to the development task but allows development to continue. Only create the branch at the point that you need to make changes.

Possible work-around for DatagridView bug

This is a link to a work around to the reentrant issue on a win forms DataGridView.

The reentrant issue raises it’s head when changing data in a DataGridView. InvalidOperation exceptions get raised a random time after the grid is changed. This implies that the DataGridView uses threads in the background yet it’s public methods are not thread-safe.

In order to solve this you should use the best practice of subclassing the UI controls and put the fix there.

Theoretically you should subclass all controls (see here) – but if pushed for time just do the complex ones (how many times will you bugfix a label?) or the subset that you use frequently – any app will mostly use 10 or so basic controls.

MSDN Magazine Lag Time

I have been reading MSDN Magazine (and it’s predecessors MSJ and Visual Developer) for a number of years now.

Until recently there has been upto a 5 year lag between an article being written and being able to use it in anger.

Today I finally found a use for an article written in June last year (only 8 months behind)!

A really useful feature  especially when combined with  Code Generation:

(I have given up on adding tags around XML) 

ItemGroup
    Compile Include="*.cs"
/ItemGroup

This allows code to be added to the project without having to explicitly edit the project file.  

Simple DataGridView Sample

This is almost all you need: 

            string connStr = “Data Source=(local);Initial Catalog=Northwind; Integrated Security=SSPI;”);
            SqlConnection conn = new SqlConnection(connStr);
            SqlCommand cmd = conn.CreateCommand();
            cmd.CommandText = “SELECT * FROM Products”;
            DataSet dataset = new DataSet();
            SqlDataAdapter dataadapter = new SqlDataAdapter(cmd);
            dataadapter.Fill(dataset,”FOO”);
            dataGridView.DataSource = dataset.Tables[“FOO”];
            dataGridView.Columns[0].Visible = false;