LINQ on Form’s Controls

December 10th, 2009 robber.baron No comments

When loading a particular form in a project of mine I needed to shift the location of most of my controls to “hide” an unused textbox based on a boolean. I was going to simply loop through each control and ignore the shift in location if the name values were the two controls that were fixed but I thought about how LINQ to Objects could help. While this is simple and probably overkill the potential is awesome.

1
2
3
4
5
6
Dim res = From ctrl In Controls.OfType(Of Control)() _
             Where ctrl.Name <> "txtAddress" AndAlso ctrl.Name <> "lblAddress"
 
For Each ctrl As Control In res
     ctrl.Top -= val
Next

Admittedly this is pretty boring. But say you wanted to change the background color of all textboxes on a form that contain a string greater than 255 and are not read only.

1
2
3
4
5
6
Dim res = From ctrl In Controls.OfType(Of TextBox)() _
             Where ctrl.Text.Length > 255 And ctrl.ReadOnly = False
 
For Each ctrl As Control In res
     ctrl.BackgroundColor = Colors.Red
Next

Very quickly you can see how LINQ can be a convenient tool for all sorts of problems. And ends up being very, very readable as well.

Memory Stats on Mobile Device

December 10th, 2009 robber.baron No comments

Recently I was working on a mobile project that was experiencing some serious memory leak issues. It turns out that I wasn’t disposing for a SqlCeResultSet properly and on each query (of which there was substantial amount) I was calling New() without Dispose().

After a day of feeling like my project was falling apart before my eyes and getting weird and unreliable results from the .NETCF Remote Profiler I searched far a wide for some way to determine the available memory on a device. On MSDN I found the following code (slightly modified by me) to get relevant information.

Basically two P/Invokes later I had the information I needed, saw that I was in fact leaking memory, quickly determined where, and restored sanity to my project. Within thirty minutes of implementing this class the world was a happier place for me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Imports System.Text
 
Public Class MEMORYSTATUSINFO
    Public Structure MEMORYSTATUS
        Public dwLength As UInt32
        Public dwMemoryLoad As UInt32
        Public dwTotalPhys As UInt32
        Public dwAvailPhys As UInt32
        Public dwTotalPageFile As UInt32
        Public dwAvailPageFile As UInt32
        Public dwTotalVirtual As UInt32
        Public dwAvailVirtual As UInt32
    End Structure
 
    Public Declare Function GlobalMemoryStatus Lib "CoreDll.Dll" _
    (ByRef ms As MEMORYSTATUS) As Integer
 
    Public Declare Function GetSystemMemoryDivision Lib "CoreDll.Dll" _
        (ByRef lpdwStorePages As UInt32, _
        ByRef ldpwRamPages As UInt32, _
        ByRef ldpwPageSize As UInt32) As Integer
 
    Public Shared Function ShowMemory() As String
        Dim storePages As UInt32
        Dim ramPages As UInt32
        Dim pageSize As UInt32
        Dim res As Integer = _
            GetSystemMemoryDivision(storePages, ramPages, pageSize)
 
        ' Call the native GlobalMemoryStatus method
        ' with the defined structure.
        Dim memStatus As New MEMORYSTATUS
        GlobalMemoryStatus(memStatus)
 
        Dim load As Integer = memStatus.dwMemoryLoad / (1024 * 1024)
        Dim totPhys As Integer = memStatus.dwTotalPhys / (1024 * 1024)
        Dim availPhys As Integer = memStatus.dwAvailPhys / (1024 * 1024)
        Dim totalPageFile As Integer = memStatus.dwTotalPageFile
        Dim availPageFile As Integer = memStatus.dwAvailPageFile
        Dim totVirtual As Integer = memStatus.dwTotalVirtual / (1024 * 1024)
        Dim availVirtual As Integer = memStatus.dwAvailVirtual / (1024 * 1024)
 
        ' Use a StringBuilder for the message string.
        Dim MemoryInfo As New StringBuilder
        MemoryInfo.Append("Memory Load: " _
            & load.ToString() & "Mb" & vbCrLf)
        MemoryInfo.Append("Total Physical: " _
            & totPhys & "Mb" & vbCrLf)
        MemoryInfo.Append("Avail Physical: " _
            & availPhys & "Mb" & vbCrLf)
        MemoryInfo.Append("Total Page File: " _
            & totalPageFile.ToString() & vbCrLf)
        MemoryInfo.Append("Avail Page File: " _
            & availPageFile.ToString() & vbCrLf)
        MemoryInfo.Append("Total Virtual: " _
            & totVirtual.ToString() & "Mb" & vbCrLf)
        MemoryInfo.Append("Avail Virtual: " _
            & availVirtual.ToString() & "Mb" & vbCrLf)
 
        ' Show the available memory.
        Return MemoryInfo.ToString()
    End Function
End Class

Hope this helps someone else find greedy memory hog code in their apps.

Linq on the Compact Framework

December 3rd, 2009 robber.baron No comments

I am a large fan of Linq when coding. I think it is a really clean and concise way to access large sets of data (whether in a database, xml, or a IList) quickly, efficiently, and in a clearly readable way.

I have been developing almost exclusively within the compact framework and while the compact framework (3.5) does not include Linq to Sql it does include Linq to XML and Linq to Objects. The problem I had was getting it to work in the compact framework.

While Imports System.Linq always failed to a lack of reference it was because there is no System.Linq.dll. The linq parts of the language are included within System.Core. Add that reference to your project and Linq will work for you.

Don’t know why it took me so long to realize this. But now I’m Linq free.

I also hear that Compact Framework 4.0 will support Linq to Sql.

Email Errors with log4net

November 11th, 2009 robber.baron No comments

On a project I have been working on I was having a terrible time getting errors from the client.  There were a plethora of database errors that I could not get to replicate on my local machine.  Simple features like adding an object to the database or editing that object to the database would error.  What is worse is that the client would not properly transcribe the error message for my debugging purposes.

To alleviate this pain I used log4net to send all errors to an email address.  This way any errors that occur within the system can be sent directly to me, without user interaction, so I might investigate without the need for a middleman.  The configuration was quite simple.

Within app.config:

    <appender name="smtpAppender" type="log4net.Appender.SmtpAppender">
      <to value="[To address]" />
      <from value="[From address]" />
      <subject value="Error" />
      <authentication value="basic" />
      <smtpHost value="[SMTP server]" />
      <username value="[SMTP username]" />
      <password value="[SMTP password]" />
      <port value="[SMTP port]" />
      <bufferSize value="10" />
      <lossy value="true" />
      <evaluator type="log4net.Core.LevelEvaluator">
        <threshold value="ERROR"/>
      </evaluator>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
      </layout>
    </appender>

This creates an appender that will send an email to the desired address with the proper smtp settings.  Once the appender is created you need to create a logger that uses the appender.

    <logger name="error-logger" additivity="false">
         <level value="ERROR" />
         <appender-ref ref="smtpAppender" /> 
    </logger>

Then whenever you want to send an error via email you just log the error as an error using the error-logger logger. This will send an email.

Personally I like giving the option to send in case the user knows what went wrong to save on spam but it isn’t a requirement. This set up worked nicely for me.

Categories: Programming Tags: ,

Value Objects

October 23rd, 2009 robber.baron No comments

Value Objects

A value object is essentially data without a sense of identity.  This simplifies them as objects within a system because they are immutable (once created they should never change), validated (since they never change should always be in a valid state), and equal (since they have no identity, two value objects with the same data are equivalent).

The best way to see this is via example.  A good example of this is money.  If you have a value object representing a sum of money then two instances of that object worth $20.00USD are equivalent regardless of the makeup of that money.  A store doesn’t care if you provide a single twenty dollar bill, two tens, four fives, or twenty ones.  They only are about receiving twenty dollars.  Thus once that value is added to their system its identity (the specific bills you handed to the cashier) is irrelevant.  A perfect example of a value object.

Immutability

If an object has no sense of identity beyond the value of its members then to change its members is to change its identities.  If you live at a particular address, the summation of street address, city, state, and zip code create the identity of that address.  The moment you change a property of your address (say zip code) the address is no longer your address.  Its identity is altered.  Thus value objects should not expose means to edit their properties.

public class Address
{
     public string StreetAddress { get; private set; }
     public string City { get; private set; }
     public string State { get; private set; }
     public string Zip { get; private set; }
 
     public Address(string streetAddress, string city, string state, string zip)
     {
          StreetAddress = streetAddress;
          City = city;
          State = state;
          Zip = zip;
     }
}

Notice that the only way to give the object value is via its constructor.  This insures that its data (and thus its identity) is never changed.  It makes the object immutable.

Validity

If an object cannot be changed then it better always be valid.  For this reason it makes sense to check that all values provided to the constructor are valid.  Thus insuring the object is always in a valid state.

public class Address
{
     public string StreetAddress { get; private set; }
     public string City { get; private set; }
     public string State { get; private set; }
     public string Zip { get; private set; }
 
     public Address(string streetAddress, string city, string state, string zip)
     {
          if (string.IsNullOrEmpty(streetAddress))
               throw new ArgumentException("Address requires street address");
          if (string.IsNullOrEmpty(city))
               throw new ArgumentException("Address requires city");
          if (string.IsNullOrEmpty(state))
               throw new ArgumentException("Address requires state");
          if (string.IsNullOrEmpty(zip))
               throw new ArgumentException("Address requires zip");
 
          StreetAddress = streetAddress;
          City = city;
          State = state;
          Zip = zip;
     }
}

Equality

Since value objects are the same if their properties are the same it makes testing their equality simple.  It becomes a simple matter of testing their properties.  For readability and convenience I tend to overload operators and the Equals method.

public class Address : IEquatable<Address>
{
     public string StreetAddress { get; private set; }
     public string City { get; private set; }
     public string State { get; private set; }
     public string Zip { get; private set; }
 
     public Address(string streetAddress, string city, string state, string zip)
     {
          if (string.IsNullOrEmpty(streetAddress))
               throw new ArgumentException("Address requires street address");
          if (string.IsNullOrEmpty(city))
               throw new ArgumentException("Address requires city");
          if (string.IsNullOrEmpty(state))
               throw new ArgumentException("Address requires state");
          if (string.IsNullOrEmpty(zip))
               throw new ArgumentException("Address requires zip");
 
          StreetAddress = streetAddress;
          City = city;
          State = state;
          Zip = zip;
     }
 
     public override bool Equals(object obj)
     {
          return Equals(obj as Address);
     }
 
     public bool Equals(Address obj)
     {
          if (obj == null)
               return false;
          return StreetAddress.Equals(obj.StreetAddress) &&
                   City.Equals(obj.City) &&
                   State.Equals(obj.State) &&
                   Zip.Equals(obj.Zip);
     }
 
     public static bool operator ==(Address left, Address right)
     {
          return Equals(left, right);
     }
 
     public static bool operator !=(Address left, Address right)
     {
          return !Equals(left, right);
     }
}

This results in a rather nice value object to work within code. Ensuring that the three important properties of a value object are met within your code.

Categories: DDD, Programming Tags:

LINQ to XML: A Mild Success Story

October 15th, 2009 robber.baron No comments

In a project I am working on I’ve come to discover the need to stitch together multiple data sources. The product itself needs to maintain a certain level of information within a database but it must also sync with a standalone application that is exporting its data.

Initially I thought this would be a nightmare to handle. Getting the exported data as XML, looping and parsing through the XML document and creating a new class and inserting it into the proper table so my project can use it. Thankfully I am all about LINQ these days (with the exception of LINQ-to-SQL) and LINQ to XML made my life amazingly simple.

Let’s take the following XML file:

<PecanProject>
  <Products>
    <Product>
      <Id>1</Id>
      <Name>Black Widget</Name>
      <Price>0.86</Price>
    </Product>
    <Product>
      <Id>2</Id>
      <Name>Yellow Widget</Name>
      <Price>0.99</Price>
    </Product>
    <Product>
      <Id>3</Id>
      <Name>Green Widget</Name>
      <Price>1.25</Price>
    </Product>
    <Product>
      <Id>4</Id>
      <Name>Red Widget</Name>
      <Price>1.11</Price>
    </Product>
  </Products>
</PecanProject>

Traditionally this sort of file would be easier to work with than a plain text file but it certainly isn’t elegant. Using LINQ to XML I can very elegantly select from the XML as though it were a normal data source and then map the results into a class.

Here is how:

var doc = XElement.Load("filename.xml");
 
var projectList = from prod in doc.Descendants("Product")
                       select new Product {
                            Id = (int)prod.Element("Id"),
                            Name = (string)prod.Element("Name"),
                            Price = (double)prod.Element("Price"),                       
                        };
 
foreach (var product in projectList)
{
     // Do something with your new product.
     PerformActionOnProduct(product);
}

This of course assumes a Product class that has three public properties named Id, Name, and Price.

This was amazingly swift, easy to code, easy to read, and will be easy to maintain. Not only that but you can actually perform calculations on the incoming code. I, for example, am importing Customers and send the address id to the address repository to actually return the proper class, rather than just the id.

It is a very clean way of doing things. I am in love.

Categories: C#, Programming Tags:

log4net with Compact Framework

October 13th, 2009 robber.baron 1 comment

My favorite logging library log4net work not only on desktop and web applications but can be used on mobile devices with the compact framework.

Granted not all of the Appenders make sense within the compact framework. Since mobile devices have neither a system log nor a console it doesn’t make much sense to have these appenders. For a complete list of supported frameworks and appenders see here.

Applications written in the compact framework don’t have app.config files.  This presents an issue when attempting to create an ILog.  Here is my work around.

First create an XML that will be copied to source on deployment.  Here is an example:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <log4net debug="false">
    <appender name="logger" type="log4net.Appender.RollingFileAppender">
      <file value="\SD Card\Assessment\DamageAssessmentLog.txt" />
      <appendToFile value="true" />
      <maxSizeRollBackups value="2" />
      <maximumFileSize value="1048576" />
      <rollingStyle value="Composite" />
      <staticLogFileName value="false" />
      <layout type="log4net.Layout.PatternLayout">
        <header value="[Header]&#13;&#10;"/>
        <footer value="[Footer]&#13;&#10;"/>
        <conversionPattern value="%newline Date: %date ,Application: %a ,Logger: %logger ,Thread: [%thread] ,Level: %level %newline Message: %message%newline Exception: %exception%newline" />
      </layout>
      </appender>
      <!-- Setup the root category, add the appenders and set the default level -->
      <root>
        <level value="DEBUG" />
        <appender-ref ref="logger" />
      </root>
    </log4net>
</configuration>

This should all be familiar so far. Basically whatever was going to go into app.config will now be in this file.

Then within your application’s startup you need to explicitly point log4net to that configuration file.

Shared Sub Main()
        Try
            Dim logconfig = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), "logging.config")
 
            log4net.Config.XmlConfigurator.Configure(New FileInfo(logconfig))
 
            Dim logger As ILog = log4net.LogManager.GetLogger("logger")
 
            Using map As formMap = New formMap()
                logger.Debug("Staring application")
                map.ShowDialog()
                logger.Debug("Application closed")
            End Using
            AssessmentConnector.Instance.CloseConnection()
        Catch ex As Exception
            MessageBox.Show(ex.ToString)
        Finally
            log4net.LogManager.Shutdown()
        End Try
    End Sub

Here you can see that I get the application’s executing path and append the xml file’s name. Then I call the log4net.Config.XmlConfigurator to initialize the logging service from the provided xml file.

Note: Due to limitations of the compact framework it is important that you call log4net.LogManager.Shutdown() to explicitly close your log files. Otherwise you’ll end up with a hanging process and open log files.

Scope Identity with SqlCe

October 6th, 2009 robber.baron No comments

Normally I write my data access layer using an ORM like nHibernate as I thoroughly enjoy the speed, flexibility and power that comes from using such tools. Recently at work, however, I have been doing a lot of Windows Mobile development and I although there are compact framework ORMs I didn’t have the experience enough to want to use one in a very important project.

As a result the following code is something I had to look up and was actually an annoying thing to find. I wanted to return the identity of a newly inserted object. Normally nHibernate would set this for me but as I’m not using nHibernate I have to do this myself.

using (connection = new SqlCeConnection(CONNECTION_STRING))
{
     connection.Open();
 
     var command = new SqlCeCommand(@"INSERT INTO photos (path, format) VALUE (?, ?) SELECT SCOPE_IDENTITY();");
     command.Parameters.Add(New SqlCeParameter());
     command.Parameters.Add(New SqlCeParameter());
     command.Parameters(0).Value = path;
     command.Parameters(1).Value = format;
 
     var id = command.ExecuteScalar();
 
     Debug.WriteLine(String.Format("New Identifier = {0}", id));
}

This is insert the photo into the database and return the new id for the photo rather than the number of rows effected. The key is the ExecuteScalar function.

How cool is it that log4net works for Compact Framework apps. Has been a huge lifesaver.

Dictionary Iteration

October 2nd, 2009 robber.baron No comments

In a project I’m working on I am storing results in a dictionary.  While I could just be storing them in a list I thought the speed and ease of use was better for a dictionary.  [In fact it turned out to be a great choice because due to collisions in the results I discovered that the data was actually bad and needed to be cleaned up.]

Once I had the results through I needed loop through them to export them to a better file format.  At first I wasn’t exactly sure how to do this.  I new a dictionary implemented the IEnumerable interface I just didn’t know how to access it.

Here is how:

var dictionary as new Dictionary();
 
dictionary.Add(obj1.GetHashCode(), obj1);
dictionary.Add(obj2.GetHashCode(), obj2);
dictionary.Add(obj3.GetHashCode(), obj3);
 
foreach (KeyValuePair result in dictionary)
{
     Console.WriteLine(String.Format("Key = {0} - Value = {1}", result.Key, result.Value.ToString());
}

Visual Basic Conditionals

October 1st, 2009 robber.baron No comments

At my current job I write far more Visual Basic code than I do C# code. Having started programming in C++ in junior year of high school and using almost exclusively C++ and Java in college, I tend to favor C based languages. One of the more natural things about C(++/#) that I found lacking in Visual Basic was intelligent conditional testing.

For example:

Dim student as Student = Nothing
 
If student IsNot Nothing And student.Name = "robber.baron" Then
     GiveStudentAnA(student)
EndIf
var student as Student = null;
 
if (student != null &amp;&amp; student.Name == "robber.baron")
     GiveStudentAnA(student);

In the C# code when the conditional is a logical And (signified by the double ampersand) and the first condition fails it immediately exits the conditional.  Since both values must be true to continue if the first is false the conditional fails and there is no need to evaluate the second condition.

In the Visual Basic code you will get a “Object Reference not set to Instance of Object” exception because Visual Basic does not implicitly have this feature.  The test for null will fail but the second condition will still be evaluated! I never liked this feature and found it to be a concrete failure in Visual Basic.

Recently I discovered that of course Visual Basic allows you to do this.  (The CLR is the CLR is the CLR.  It is all common under the hood.)  It just needs to you explicitly request this behavior using the AndAlso or OrElse keywords.

Dim student as Student = Nothing
 
If student IsNot Nothing AndAlso student.Name = "robber.baron" Then
     GiveStudentAnA(student)
EndIf

This is how you would properly translate the C# code above into Visual Basic.

If you wanted the inverse, you only wanted the right side condition to evaluate only if the left is true you could do the following:

Dim student as Student = new Student("robber.baron", "C")
 
If student.Name = "robber.baron" OrElse Not student.Grade = "A" Then
     GiveStudentAnA(student)
EndIf

Finally I can combine null checks and logic checks into a single conditional correctly.

Categories: Programming, Visual Basic Tags: