December 21, 2014

Weak References with Compiled Transforms

There is a good description of this generic WeakReference<> class here.
Here is an example of using WeakReferences for caching XslCompiledTransform's:
private static Dictionary<string, WeakReference<XslCompiledTransform>> xsltLookupTable = 
  new Dictionary<string, WeakReference<XslCompiledTransform>>();

public XslCompiledTransform GetCompiledTransform(string xslFileName)
{
    XslCompiledTransform xct = null;
    bool found = xsltLookupTable.ContainsKey(xslFileName);
    if (found) // IF the transform is already cached
    {   // Try and get it
        WeakReference<XslCompiledTransform> xctWr = xsltLookupTable[xslFileName] 
           as WeakReference<XslCompiledTransform>;
        xctWr.TryGetTarget(out xct); // Try and get it from the WeakReference
        m_logger.WriteTrace("Found XslCompiledTransform entry for \'" + 
           xslFileName + "\' in the cache");
        // Note the entry maybe null (if the weak reference expired)
    }
        
    if (xct == null) // IF the compiled transform was not already cached
    {
        // Create it
        xct = new XslCompiledTransform();
        xct.Load(xslFileName, 
          new XsltSettings { EnableDocumentFunction = true }, 
          new XmlUrlResolver());
        // Insert it into a WeakReference
        WeakReference<XslCompiledTransform> wr = new 
          WeakReference<XslCompiledTransform>(xct);
        if (found)
        {
          m_logger.WriteTrace("Removing XslCompiledTransform entry for \'" + 
              xslFileName + "\' as it was null in the cache");
          xsltLookupTable.Remove(xslFileName);
        }
        xsltLookupTable.Add(xslFileName, wr); // Add the WeakReference to the cache
        m_logger.WriteTrace("Adding XslCompiledTransform entry for \'" + 
          xslFileName + "\'");
    }
    return xct;
}
It uses the new generic WeakReference<> class (available in .NET 4.5?). This class could be further refactored into a generic caching class if it was required.

December 12, 2014

Configuring log4net for specific classes or namespaces

Here is some sample xml that goes in the application config file.
<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    ...
  </configSections>
  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
      <mapping>
        <level value="ERROR" />
        <foreColor value="Red, HighIntensity" />
      </mapping>
      <mapping>
        <level value="WARN" />
        <foreColor value="Yellow" />
      </mapping>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%utcdate [%t] %-5p [] - %m%n"/>
      </layout>
    </appender>
    <appender name="OutputDebugStringAppender" type="log4net.Appender.OutputDebugStringAppender">
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%utcdate [%t] %-5p %c [] - %m%n"/>
      </layout>
    </appender>
    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
      <file value="FilePath.txt" />
      <appendToFile value="true" />
      <maximumFileSize value="1000KB" />
      <maxSizeRollBackups value="20" />
      <param name="RollingStyle" value="Size" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%utcdate [%t] %-5p %c [] - %m%n" />
      </layout>
    </appender>
    <root>
      <level value="INFO"/>
      <appender-ref ref="RollingFile"/>
      <appender-ref ref="ConsoleAppender"/>
      <appender-ref ref="OutputDebugStringAppender"/>
    </root>
    <!--Level values are DEBUG, INFO, WARN, ERROR -->
    <!--Entries for "top level" server module classes, to allow tracing of method calls -->
    <logger name="Some.Name.Space.ClassA.">
      <level value="INFO"/>
    </logger>
    ...
    <!--Entries for namespaces, to allow full tracing inside modules -->
    <logger name="Some.Particular.Namespace">
      <level value="INFO"/>
    </logger>
    ...
    <!--Entries for certain individual classes -->
    <logger name="Some.Deep.Level.NameSpace.SpecificClass.">
      <level value="DEBUG"/>
    </logger>
    ...
  </log4net>
...  
</configuration>

December 5, 2014

CallerMemberNameAttribute in .NET 4.5

Use of "CallerMemberNameAttribute" for an IPropertyNotifyChanged base class implementation
More declaration info can be found here

I found that this did not work in VS 2010 but did work in VS 2013 as it is compiler dependent. You need to install KB2468871 on top of .net 4 framework to be able to use. Alternatively, you can simply define the attribute yourself to get it to work.
namespace System.Runtime.CompilerServices
{
  /// 
  /// Allows you to obtain the method or property name of the caller.
  /// 
  [AttributeUsageAttribute(AttributeTargets.Parameter, Inherited = false)]
  public sealed class CallerMemberNameAttribute : Attribute { }
}
Here is an example of how to use it to make a simple logger (only 1 method shown):
class SimpleLogger 
{
...
 public void Error(
   [CallerMemberName] string memberName = "",
   [CallerFilePath] string sourceFilePath = "",
   [CallerLineNumber] int sourceLineNumber = 0,
   string message)
 {
    Debug.Write(" Method/Property=" + memberName);
    Debug.Write(" SourceFilePath=" + sourceFilePath);
    Debug.Write(" SourceLineNumber=" + sourceLineNumber);
    Debug.WriteLine(" - " + message);

 }
...
}
and invoking it:
SimpleLogger logger = new SimpleLogger();
...
catch(Exception ex)
{
  logger.Trace(" Exception caught " + ex.ToString()); // The attributed parameters are inserted by the compiler at compile time
}

November 18, 2014

When is a Hyphen not a Hyphen?

Take a look at these 2 command line strings:
CASE 1:
"%windir%\Microsoft.NET\Framework\v2.0.50727\caspol.exe" -machine -addgroup All_Code 
-site 192.168.45.111 FullTrust -name "XXX : 192.168.45.111" -description 
"Allows full trust privileges to XXX Public Safety Applications"
CASE 2:
"%windir%\Microsoft.NET\Framework\v2.0.50727\caspol.exe" -machine -addgroup All_Code 
-site 192.168.45.111 FullTrust –name "XXX : 192.168.45.111" –description 
"Allows full trust privileges to XXX Public Safety Applications"

While the first one succeds the 2nd one fails. When we converted the "-name" in the first one to hex we got
2D6E616D65
Whereas in the second we got
966E616D65

The hyphen in the first is a hyphen but in the second one it is in fact a "non-breaking hyphen". This is just visible in this email but in a notepad editor they may look exactly the same.
The morale of the story is: Beware of command line arguments copied from 3rd party sources

November 6, 2014

Debug with an IntegerOptionFile

Sometimes it is useful when debugging within an application to change the logic using an external influence, for example, using a value in a file. I have made the class as small as possible so that it can be copied and pasted anywhere for temporary debugging help Something that can be used like this:
...
int myOption = IntegerOptionFile.WriteValue(1)
...
int myOption = IntegerOptionFile.ReadValue()
if (myOption == 1)
{
    PerformSomeOptionalCode()
}
...
Here we can change a special option file and have the code change behaviour:
using System.IO;
...
// Use this to help debug an application by writing code
// that can be switched by reading a value from a text file
internal static class IntegerOptionFile
{
    private static readonly string optionFilePath = Path.Combine(
        Path.GetTempPath(), "intoption.txt");

    public static void WriteValue(int option)
    {
        File.WriteAllText(optionFilePath, option.ToString());
    }

    // Consider defining a suitable default value
    public static int ReadValue(int def = default(int))
    {
        int option = def;
        bool res = File.Exists(optionFilePath);
        if (!res)
        {
            WriteValue(def);
        }
        res = File.Exists(optionFilePath);
        if (res)
        {
            string tmp = File.ReadAllText(optionFilePath);
            if (tmp.Length > 0)
            {
                int.TryParse(tmp, out option);
            }
        }
        return option;
    }
}
By using a text file we can change the value from a simple notepad editor and have the running program change behaviour immediately. Note that this is only temporary code used for debugging/investigating a problem, not for release code.

October 30, 2014

Using Linq To Sql

To use LinqToSql in a project:
First add "System.Data.Linq" reference to the project
Map the Entity Classes to Tables. Need a "[Table]XxxTable" class per table with appropriate properties for each column. Note that the columns names have to match the property names. Although this table class maps to the Db table an instance of it represents a row in the table. For example:
// Table mapping entity for the MyTableRow table row
[Table(Name = "MyTable")]
internal class MyTableRow
{
    // Default constructor is Required for Linq to Sql
    public MyTableRow()
    {
    }

    /////////////////////////////////
    // Database columns defined here

    [Column(IsPrimaryKey = true, IsDbGenerated = true)]
    public int Id { get; set; }

    [Column(CanBeNull = false)]
    public string Name { get; set; }

    [Column(DbType = "Bit NOT NULL")]
    public bool IsMandatory { get; set; }
}
This maps to a row in the SQL table "MyTable". Need a "DataContext" derived class to access these tables, call it xxxDataContext. Mark it with the "[Database]" attribute. For example:
// Linq to SQL data context for accessing the DB 
[Database]
internal class MyDataContext : DataContext
{
    // Constructor
    public MyDataContext(string connectionString)
        : base(connectionString)
    {
    }
}
Found that making the correct key definitions (including foreign keys) on the SQL tables was critical to getting the Linq to Sql working. With those definitions we can start to query the DB using Linq.
Querying SQL with LINQ
LINQ to SQL: .NET Language-Integrated Query for Relational Data
private void CreatePattern(
    MyDataContext dbAccess, 
    MyTableRow[] toCreate)
{
    var table = dbAccess.GetTable<MyTableRow>();
    table.InsertAllOnSubmit(toCreate);
    dbAccess.SubmitChanges();
}

private MyTableRow[] ReadPattern()
{
    var allRows = new MyTableRow[0];
    using (var dbAccess = new MyDataContext(GetDatabaseConnectionString()))
    {
        var table = dbAccess.GetTable<MyTableRow>();
        allRows = table.ToArray();
    }
    return allRows.ToArray();
}

private void UpdatePattern(
    MyAdminContext dbAccess, 
    MyTableRow[] changed)
{
    var table = dbAccess.GetTable<MyTableRow>();
    foreach (var target in changed)
    {
        // Find row to update in the table
        var id = target.Id;
        var row = table.FirstOrDefault(rowx => rowx.Id == id);
        if (row != null) // IF it was found
        {
            // Copy the changes from target into the row
            UpdateRow(row, target); 
        }
    }
    dbAccess.SubmitChanges(); 
}

private void DeletePattern(
    MyDataContext dbAccess, 
    MyTableRow[] deleted)
{
    var table = dbAccess.GetTable<MyTableRow>();

    foreach (var target in deleted)
    {
        // Find row to delete in the table
        var id = target.Id;
        var row = table.FirstOrDefault(ipdx => ipdx.Id == id);
        if (row != null) // Was it found?
        {
            table.DeleteOnSubmit(row);
        }
    }
    dbAccess.SubmitChanges();
}
There are 2 ways to create transactions; using the TransactionScope class and using the standard DbTransaction class.
Using new TransactionScope() Considered Harmful
All About TransactionScope
Using Transaction Scope (need to add the System.Transactions assembly in the references)
using System.Transactions;
...
using (var scope = TransactionScopeFactory.CreateTransactionScope()) // Asscociate all the changes with 1 transaction
{
    // Use 1 data context for all operations, in this case MS DTC will not be used
    // See http://weblog.west-wind.com/posts/2009/Jul/14/LINQ-to-SQL-and-Transactions 
    // paragraph 'TransactionScope DTC Requirements'
    using (var dbAccess = new MyDataContext (GetDatabaseConnectionString()))
    {
        MakeDbChangesUsingLinqToSql(dbAccess);

        scope.Complete();
        log.WriteInfo("Transaction completed, the database changes are committed.");
    }
}
Using a DbTransaction
using (var dbAccess = new MyDataContext(GetDatabaseConnectionString()))
{
    dbAccess.Connection.Open();
    // To absolutely guarantee that the MS DTC will not be used (which can occur when using TransactionScope) 
    // we will use a standard DB transaction here
    dbAccess.Transaction = dbAccess.Connection.BeginTransaction();
    
    try
    {
        MakeDbChangesUsingLinqToSql(dbAccess);
    
        dbAccess.Transaction.Commit(); // No exceptions so commit the changes
        log.WriteInfo("Transaction completed, the database changes are committed.");
    }
    catch (Exception) // Rollback if any exception is encountered
    {
        dbAccess.Transaction.Rollback();
        throw;
    }
}

October 20, 2014

Async/Await

Best explanation I have found
Looking underneath the hood
More complicated but diagrammed example here

The “async” keyword tells compiler that the method may return asynchronously, it enables the use of the await keyword. The beginning of an async method is executed just like any other method, it runs synchronously until it hits an “await” (or throws an exception).

The “await” keyword is where things can get asynchronous. Await is like a unary operator: it takes a single argument, an awaitable (an “awaitable” is an asynchronous operation). Await examines that awaitable to see if it has already completed; if the awaitable has already completed, then the method just continues running synchronously just like a regular method.

If “await” sees that the awaitable has NOT completed, then it acts asynchronously. It tells the awaitable to run the remainder of the method when it completes, and then returns from the async method.

Careful with a method that leaves a lot of data on the stack. This data will stay around until the async method is complete, ie all "async" tasks have completed.
private static async void DoSomethingAsync()
{
    var result = await SomeTask(args);
    DoSomethingWithResult(result);    
}

May 13, 2014

Searching for text within files using Linq

A good example of the power of Linq:
Directory.EnumerateFiles(@"S\Source\", "*.*proj", SearchOption.AllDirectories)
    .SelectMany(file => File.ReadAllLines(file).Select((text,n)=> new {text,lineNumber=n+1,file}))
    .Where(line => Regex.IsMatch(line.text,@"SccProjectName"))
    .Where(line => !Regex.IsMatch(line.text,@"SAK"))
    .Dump("Should be set to SAK")

February 18, 2014

Routing Events to Commands in WPF using MVVM Light

First reference some assemblies:
  • System.Windows.Interactivity
  • GalaSoft.MvvmLight.Extras.WPF4
In the XAML file add references to the namespaces in the window definition:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
Within you window component, add the event to command handler's
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=LoadedCommand}"
                        PassEventArgsToCommand="True" />
    </i:EventTrigger>
    <i:EventTrigger EventName="Closing">
        <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=ClosingCommand}"
                        PassEventArgsToCommand="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>
Then some code to process the command:
private RelayCommand<RoutedEventArgs> loadedCmd;

public RelayCommand<RoutedEventArgs> LoadedCommand
{
  get
  {
    return this.loadedCmd ?? (this.loadedCmd = new RelayCommand<RoutedEventArgs>
    ((rea) => 
    {
      // Use event argument 'rea' if you need it 
      // (but PassEventArgsToCommand="True" is needed in the Xaml, see above)
      this.ActivityText = "Copy files from \'" +
         m_AsyncPhotoBackup.TargetDirectory +
         "\' to \'" +
         m_AsyncPhotoBackup.DestinationDirectory +
         "\'.";
      m_AsyncPhotoBackup.RunWorkerAsync();
    }));
  }
}

TaskbarItemInfo in MVVM and Sample WPF Converter Usage

In this case we are using a WPF TaskbarItemInfo to show progress on an icon in the Taskbar. The taskbar progress value takes a double value between 0.0d and 1.0d. However, in this cae the progresss value is generated as an integer percentage between 0 and 100. So we create a converter class to convert our interger value between 0 and 100 to the double value. An alternative would be to create another property that creates the progress value in the appropriate form.
// Convert an integer percentage (0 to 100) to a double 
// between (0.0d and 1.0d)
public class IntPercentageToDoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        double res = 0.0d;
        if (value is int)
        {
            int intVal = (int)value;
            res = intVal / 100.0d;
            if (res < 0.0d)
                res = 0.0d;
            else if (res > 100.0d)
                res = 100.0d;
        }
        return res;            
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        return null;
    }
}
In the Xaml we first need to create an instance of the converter. A few namespace declarations are required:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PhotoBackupApp.ViewModel"
Create the converter instance:
<Window.Resources>
    <local:IntPercentageToDoubleConverter x:Key="intPercentageToDoubleConverter" />
</Window.Resources>
Use the converter with the bound proprety
<Window.TaskbarItemInfo>
    <TaskbarItemInfo ProgressValue="{Binding Mode=OneWay, 
       Path=ProgressPercentage, 
       Converter={StaticResource intPercentageToDoubleConverter},
       UpdateSourceTrigger=PropertyChanged}" 
       ProgressState="Normal" />
</Window.TaskbarItemInfo>
The 2 important declarartions here are 'Path=ProgressPercentage, Converter={StaticResource intPercentageToDoubleConverter},'. This is the property to bind to and the converter instance to use.

Closing a Dialog Window in WPF using MVVM

Alot of ideas are mentioned on this website:
http://stackoverflow.com/questions/4376475/wpf-mvvm-how-to-close-a-window

Simplest way is to simply define the close button as normal using the click event
<Button Content="OK" IsDefault="True" Click="okButton_Click" />
Here is the code behind:
private void okButton_Click(object sender, RoutedEventArgs e)
{
 this.Close();
}
This does not affect the ViewModel in any way, the ViewModel knows nothing about the close functionality. and there is nothing wrong with code behind if it does not affect the ViewModel.
However I wanted to be able to initiate the Close from the ViewModel. To do this I defined a property that takes a simple Action delegate
public Action CloseAction { get; set; }
In the constructor I give it a default value
this.CloseAction = () => 
    { Debug.WriteLine("ActivePhotoBackupViewModel - Close Action Undefined"); )};
Now I can use a command to perform the CloseAction
#region Done Command
private RelayCommand doneCommand;

public RelayCommand DoneCommand
{
 get
 {
  return this.doneCommand ?? 
    (this.doneCommand = new RelayCommand(() => 
     {
      DoSomeOtherStuffHere();
      this.CloseAction();
     }
    ));
 }
}
#endregion Done Command
When creating the view model the close action is defined:
...
ActivePhotoBackupViewModel vm = new ActivePhotoBackupViewModel(srcDir, destDir, photoBackupOptions);
PhotoBackupDlg photoBackupDlg = new PhotoBackupDlg();
vm.CloseAction = new Action(() => photoBackupDlg.Close());
...
Could have a used an interface here on a class to perform the same work but then the interface would have had one method so it is simpler just to use a delegate instead ('Action' is a system defined delegate). Also there were no future extra requirements envisaged on this interface (otherwise the interface route would have been worth it). This simple solution does not impede any unit testing of the ViewModel either.