PostSharp with SharpDevelop

SharpDevelop3.0 uses MSBuild. Including PostSharp in your build process is transparent if you are doing a global install using PostSharp installer. If you are doing a per-project installation using “Binary – No Installer” download, you will need to import the PostSharp targets into your .csproj file –


    True

C:\code\PostSharp-1.0.8.316-Binary\

For more details, read the install instructions included in the PostSharp download and under-the-hood-of-msbuild-integration.

To use local PostSharp binaries (relative to your project) , modify your .csproj file as follows –

  
    True
    $(MSBuildProjectDirectory)\PostSharp\
  
  
  
  
    

$(MSBuildProjectDirectory) is the directory containing your .csproj file.
\PostSharp\ is the directory containing local PostSharp binaries.

2. You will need to exclude the Aspect class itself from being woven.

If you are following the getting-started sample, see the following example:

[Serializable]
[Trace( null, AttributeExclude = true )]
public sealed class TraceAttribute : OnMethodBoundaryAspect
{

3. Compile your project.

Using Custom Converter in XAML

In my previous post : WPF-LINQ To SQL Sample, I had to resort to modifying .dbml file to get the images stored as varbinary into the WPF ListView control. I had to change the Type of image fields to System.Byte[], instead of using System.Data.Linq.Binary. A better way to do this is to use a custom converter. WPF allows you to specify custom converter as part of the Binding in .xaml, like this –

<Image Grid.Row="2"
Source="{Binding Path=ThumbNailPhoto ,
Converter={StaticResource imageConverter}}"></Image>

The custom converter is declared in the same .xaml file as a resource –

<Window.Resources>
<local:ImageDataConverter x:Key="imageConverter" />
</Window.Resources>

ImageDataConverter is implemented in .xaml.cs file –

public class ImageDataConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter,
   System.Globalization.CultureInfo culture)
   {
      byte[] image = ((System.Data.Linq.Binary)value).ToArray();
      return image;
   }

   public object ConvertBack(object value, Type targetType, object parameter,
   System.Globalization.CultureInfo culture)
   {
      throw new NotSupportedException();
   }
}

The updated sample code can be downloaded here : WPF-LINQ to SQL Sample
License : Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.

WPF – LINQ to SQL Sample

This exercise in binding a WPF ListView control with LINQ to SQL was a lot of fun ! The following image shows data from AdventureWorks sample database displayed in the ListView control. The end result is very admirable, even in this very basic demo. Feeling a complete sense of freedom is unavoidable when working with WPF.

Linq2SqlSample1.Png

This sample demonstrates :

  1. LINQ to SQL mapping.
  2. WPF ListView Control DataBinding.
  3. Displaying images stored in database as varbinary in WPF control.

The sample code can be downloaded here : WPF-LINQ to SQL Sample
License : Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.

Creative Commons License

Customize log4net Output Path

The default log4net output path is relative to the startup directory of your executable. To customize the output path, you can override the base Appender’s File property in your own Appender class. The following example describes how to route the log files relative to the temp folder :

   public class MyOwnAppender : log4net.Appender.RollingFileAppender
   {
         public override string File
         {
             get
             {
                 return base.File;
             }

            set
            {
                if (Path.IsPathRooted(value))
                {
                    base.File = value;
                }
                else
                {
                    base.File = Path.Combine(Path.GetTempPath(), value);
                }
            }
        }
    }

Your log4net config file must be modified so that log4net can locate and use your custom Appender. If MyOwnAppender is in MyNamespace and you have implemented it in MyLoggerLib.dll :


Leveraging XPATH Axes

XPATH axes come in very handy when nodes need to be selected based on (attribute’s or child element’s) values that must match those of other nodes elsewhere in the xml tree. Consider the following log4net configuration file :


<?xml version="1.0"?>

<configuration>
    <configSections>
        <section name="nhibernate"
            type="System.Configuration.NameValueSectionHandler, System,
            Version=2.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <section name="log4net"
            type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
    </configSections>
    <nhibernate>
        <add key="hibernate.connection.provider"
            value="NHibernate.Connection.DriverConnectionProvider" />
        <add key="hibernate.connection.driver_class"
            value="NHibernate.Driver.SqlClientDriver" />
        <add key="hibernate.connection.connection_string"
            value="Server=servername; Database=dbname;
            User=username; Password=secret;" />
        <add key="hibernate.connection.isolation" value="ReadCommitted" />
        <add key="hibernate.dialect"
            value="NHibernate.Dialect.MsSql2000Dialect" />
    </nhibernate>

    <log4net>
        <appender name="NHibernateFileLog"
        type="log4net.Appender.RollingFileAppender">
            <file value="Logs/nhibernate.txt" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="10" />
            <maximumFileSize value="100KB" />
            <staticLogFileName value="true" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern
                value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n"  />
            </layout>
        </appender>

        <appender name="GeneralLog"
            type="log4net.Appender.RollingFileAppender">
            <file value="Logs/general.txt" />
            <appendToFile value="true" />
            <maximumFileSize value="100KB" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="5" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern
                value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n"  />
            </layout>
        </appender>
        <appender name="DataLog"
            type="log4net.Appender.RollingFileAppender">
            <file value="Logs/data.txt" />
            <appendToFile value="true" />
            <maximumFileSize value="100KB" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="5" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern
                value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n"  />
            </layout>
        </appender>

        <!-- levels: DEBUG, INFO, WARN, ERROR, FATAL -->

        <root>
            <level value="DEBUG"/>
            <appender-ref ref="GeneralLog" />
        </root>

        <logger name="NHibernate" additivity="false">
            <level value="DEBUG"/>
            <appender-ref ref="NHibernateFileLog"/>
        </logger>
        <logger name="Pushable.Data" additivity="false">
            <level value="DEBUG"/>
            <appender-ref ref="DataLog"/>
        </logger>
    </log4net>
</configuration>


The <appender>s are referenced by <logger>s using ‘ref’ attribute of their ‘appender-ref’ child elements, using the same value as the ‘name’ attribute of the <appender>. This type of linking is quite common in xml documents. Now, The first question is : How to list files that are referenced by <logger>s ?
In order to solve this problem you will need to reach the <appender>s that are referenced by each <logger> and then extract the ‘value’ of their <file>s.


Solution:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="log4net">
        <xsl:apply-templates
            select="appender[@name=parent::log4net/logger/appender-ref/@ref]"/>
    </xsl:template>

    <xsl:template match="appender">
        <xsl:value-of
            select="file/@value"/> <xsl:text>&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>


The second question is : How to write an xslt script to transform this xml document into an html document with a table that looks like this –

NHibernate Logs/nhibernate.txt
Pushable.Data Logs/data.txt

Solution:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

    <xsl:output method="html"/>

    <xsl:template match="log4net">
        <HTML>
            <HEAD>
                <TITLE>www.tewari.info : using xpath axes</TITLE>
            </HEAD>
            <BODY>
                <TABLE border="1" width="25%">
                    <TR><TH>Logger</TH><TH>File</TH></TR>
                    <xsl:apply-templates select="logger"/>
                </TABLE>
            </BODY>
        </HTML>
    </xsl:template>

    <xsl:template match="logger">
            <xsl:variable name="aName" select="appender-ref/@ref"/>
            <TR>
            <TD><xsl:value-of select="@name"/></TD>
            <TD><xsl:value-of
                select="parent::log4net/appender[@name=$aName]/file/@value"/></TD>
            </TR>
    </xsl:template>

</xsl:stylesheet>


Credits :

  • SketchPath is a brilliant tool to play with xpath. I love the “New Context” button : Click on a node and hit “New Context” to change the context for the xpath query processor !