<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Simon Rice - Blog</title>
	<atom:link href="http://www.simonrice.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.simonrice.com/blog</link>
	<description>Jottings of a programmer</description>
	<lastBuildDate>Sun, 21 Feb 2010 17:53:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>When Spark meets ASP.NET WebForms</title>
		<link>http://www.simonrice.com/blog/2010/02/21/when-spark-meets-asp-net-webforms/</link>
		<comments>http://www.simonrice.com/blog/2010/02/21/when-spark-meets-asp-net-webforms/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 17:03:37 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Short Guides]]></category>
		<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[spark]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[view engine]]></category>
		<category><![CDATA[webforms]]></category>

		<guid isPermaLink="false">http://www.simonrice.com/blog/?p=20</guid>
		<description><![CDATA[This short guide will provide a proof of concept for an alternative to the traditional ASP.NET (WebForms) templated controls &#38; provide an insightful use for the powerful Spark template engine that hasn&#8217;t been mentioned elsewhere.
The Spark template engine is a well-documented, open source view engine for .NET, mainly used as an alternative to the &#8220;WebForms&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>This short guide will provide a proof of concept for an alternative to the traditional ASP.NET (WebForms) templated controls &amp; provide an insightful use for the powerful Spark template engine that hasn&#8217;t been mentioned elsewhere.</p>
<p>The <a href="http://www.sparkviewengine.com/" target="_blank">Spark template engine</a> is a well-documented, open source view engine for .NET, mainly used as an alternative to the &#8220;WebForms&#8221; engine built into ASP.NET MVC.  It can also be used with <a href="http://www.castleproject.org/monorail/index.html" target="_blank">Castle MonoRail</a> or even in a standalone application (for example, a console application that creates emails from a template &amp; sends them).  What excites me about this particular template engine is much of its syntax is derived by adding a few extra tags &amp; attributes to HTML, allowing for a cleaner look for your template while not sacrificing the page&#8217;s rendering performance (unlike with other templating engines).  Taking the example on the front page of the Spark website, a bit of WebForms code that is written like this&#8230;&#8230;.</p>
<pre class="brush: xml;">
&lt;% (IEnumerable&lt;Product&gt; products = (IEnumerable&lt;Product&gt;)ViewData[&quot;products&quot;]; %&gt;
&lt;% if (products.Any())
    { %&gt;
        &lt;ul&gt;
            &lt;% foreach (Product p in products)
                { %&gt;
                     &lt;li&gt;&lt;%= p.Name %&gt;&lt;/li&gt;
            &lt;% } %&gt;
        &lt;/ul&gt;
    } else { %&gt;
        &lt;p&gt;No products available&lt;/p&gt;
&lt;% } %&gt;
</pre>
<p>&#8230;can simply be expressed using Spark as:</p>
<pre class="brush: xml;">
&lt;viewdata products=&quot;IEnumerable[[Product]]&quot;/&gt;
&lt;ul if=&quot;products.Any()&quot;&gt;
  &lt;li each=&quot;var p in products&quot;&gt;${p.Name}&lt;/li&gt;
&lt;/ul&gt;
&lt;else&gt;
  &lt;p&gt;No products available&lt;/p&gt;
&lt;/else&gt;
</pre>
<p>If you&#8217;re unfamiliar with Spark &amp; I&#8217;ve got you interested in it, it&#8217;s well worth looking at <a href="http://www.sparkviewengine.com/documentation" target="_blank">the documentation</a> for more syntactic tricks it can perform.</p>
<p>One problem we&#8217;ve continuously been running up against is we&#8217;ve had to build a server control on an ASP.NET WebForms project that produces custom HTML depending on values from our model.  However, because we&#8217;re building these custom server controls for a Content Management System, we don&#8217;t have access to the page object, any form of code behind or anything from the model when we need them &#8211; the only way we can define them is on an ASCX template that lacks a code behind.  This rules out any conditional logic where we define the template, &amp; results in the dreaded HTML strings written in the control&#8217;s .cs file if we wanted to do more than using simple WebForms controls.</p>
<p>What I thought would be nice is to have a custom control with a spark template as its children, with the code for the control only dealing with fetching the domain model &amp; assembling a view model.  Something like:</p>
<pre class="brush: xml;">
&lt;sc:MySparkControl runat=&quot;server&quot;&gt;
    &lt;ul if=&quot;products.Any()&quot;&gt;
        &lt;li each=&quot;var p in products&quot;&gt;${p.Name}&lt;/li&gt;
    &lt;/ul&gt;
    &lt;else&gt;
        &lt;p&gt;No products available&lt;/p&gt;
    &lt;/else&gt;
&lt;/sc:MySparkControl&gt;
</pre>
<p>The great thing is this idea is possible to implement!  What you need to do is create a new control that is derived from System.Web.UI.WebControls.Literal.  What you then do is very similar to what you do <a href="http://whereslou.com/2008/12/16/using-spark-as-a-general-purpose-template-engine" target="_blank">when running spark from a standalone application</a>.  The main difference is the template is the Text property of the control:</p>
<pre class="brush: csharp;">
public class Product
{
    public Product(int id, string name)
    {
        ID = id;
        Name = name;
    }

    public int ID
    {
        get;
        protected set;
    }

    public string Name
    {
        get;
        set;
    }
}

public abstract class MyViewModel : AbstractSparkView
{
    public IEnumerable&lt;Product&gt; products { get; set; }
}

public class MySparkControl : Literal
{
    protected override void OnPreRender(EventArgs e)
    {
        /* Set up spark with its settings, with an in-memory view
           folder since we don't wish to use any external files */

        SparkSettings settings = new SparkSettings().SetPageBaseType(typeof(MyViewModel));

        InMemoryViewFolder templates = new InMemoryViewFolder();
        SparkViewEngine engine = new SparkViewEngine(settings)
        {
            ViewFolder = templates
        };

        /* Add template - note we still need to specify a name even
           though everything is in memory */

        templates.Add(&quot;template.spark&quot;, this.Text);

        // Render template
        SparkViewDescriptor descriptor = new SparkViewDescriptor().AddTemplate(&quot;template.spark&quot;);

        StringWriter output = new StringWriter();

        var view = (MyViewModel)engine.CreateInstance(descriptor);

        IEnumerable&lt;Product&gt; myProducts;
        // Fetch the products at this point &amp; put them in myProducts

        view.products = myProducts;
        view.RenderView(output);

        this.Text = output.ToString();

        base.OnPreRender(e);
    }
}
</pre>
<p>Here I&#8217;ve also thrown in a view model &amp; a basic product class for the sake of demonstration.</p>
<p>Provided you fill in some code to initialise the myProducts IEnumerable &amp; do all of the web.config setting up for this control, it will give you a list of the names of the products given.  No HTML written in C# strings, &amp; you have full flow of control from within your template with the power &amp; ease of the Spark syntax.  The one drag I&#8217;ve discovered is you cannot use the traditional &lt;%= %&gt; notation from within the control template, but I personally feel this is a minor drawback as the alternatives offered by Spark (!{ } for without HTML encoding or ${ } with it) are much neater.</p>
<p>For my purposes this implementation will do the job fine.  But there are additions that I invite any reader to implement.   First of all, what if we can bind this control to a WebForms data source, such as a LINQ, SQL, or Object Data Source control?   This may mean we can even have a rival to the GridView, Repeater, etc. on our hands.  Another nice idea may be to have the ability to specify the location of an on-disk template as a parameter to the control.   This idea of a template on WebForms tag isn&#8217;t just limited to Spark &#8211; there are other view engines you may well be able to carry this to, such as <a href="http://code.google.com/p/nhaml/" target="_blank">NHaml</a>, <a href="http://www.ndjango.org/" target="_blank">NDjango</a>, <a href="http://nvelocity.codeplex.com/" target="_blank">NVelocity</a> &amp; <a href="http://www.castleproject.org/MonoRail/documentation/trunk/viewengines/brail/index.html" target="_blank">Brail</a>.</p>
<p>Happy templating!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simonrice.com/blog/2010/02/21/when-spark-meets-asp-net-webforms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Log4SSIS</title>
		<link>http://www.simonrice.com/blog/2010/02/14/log4ssis/</link>
		<comments>http://www.simonrice.com/blog/2010/02/14/log4ssis/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 19:16:24 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Short Guides]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[commons logging]]></category>
		<category><![CDATA[dts]]></category>
		<category><![CDATA[log4net]]></category>
		<category><![CDATA[ssis]]></category>

		<guid isPermaLink="false">http://www.simonrice.com/blog/?p=9</guid>
		<description><![CDATA[This short guide, my first of many I hope, will show you how to route log messages from SQL Server Integration Services, or SSIS, to a log provider like log4net or Commons  Logging when running a package from a console application.
For one of my projects, we were (over)using SSIS for a number of automated [...]]]></description>
			<content:encoded><![CDATA[<p>This short guide, my first of many I hope, will show you how to route log messages from SQL Server Integration Services, or SSIS, to a log provider like <a href="http://logging.apache.org/log4net/" target="_blank">log4net</a> or <a href="http://netcommon.sourceforge.net/" target="_blank">Commons  Logging</a> when running a package from a console application.</p>
<p>For one of my projects, we were (over)using SSIS for a number of automated data integration tasks.  <a href="http://www.persistall.com/archive/2008/03/06/reason-94532-to-hate-ssis.aspx" target="_blank">It</a> <a href="http://ayende.com/Blog/archive/2007/04/05/SSIS-Integration-Woes.aspx" target="_blank">has</a> <a href="http://persistall.com/archive/2007/07/18/ayende-nails-ssis-faults.aspx" target="_blank">been</a> <a href="http://www.facebook.com/group.php?gid=6481811710" target="_blank">documented</a> elsewhere that SSIS does have a number of shortcomings.  I&#8217;ve quite often had the nightmare of having to write out task scripts in Visual Basic* when SSIS didn&#8217;t have the right task for me.  Plus we were seriously being let down by its poor logging, especially when attempting to trace problems through SQL Server Management Studio.  We had also moved our version control rightfully from Visual SourceSafe to Subversion, but an SSIS package won&#8217;t work well with SVN as it&#8217;s literally 1 long line!</p>
<p>So we&#8217;ve decided that we&#8217;ll eventually re-write all of our tasks as custom C# programs (as an aside, we&#8217;re using <a href="http://quartznet.sourceforge.net/" target="_blank">Quartz.NET</a> to perform internal scheduling &amp; provide us with some simple concurrency).  Some of these tasks have been trivial to implement, but others need more time &amp; therefore budget to move over.  However, we could benefit from improved logging from day 1 yet still use some SSIS tasks for now.</p>
<p>The idea here is to run an SSIS task from a C# console application &amp; have all of the log messages from SSIS sent to a log provider like <a href="http://netcommon.sourceforge.net/" target="_blank"></a><a href="http://logging.apache.org/log4net/" target="_blank">log4net</a> or <a href="http://netcommon.sourceforge.net/" target="_blank">Commons  Logging</a>.   The idea was that we can log useful messages to an XML file, do away with useless debug messages like verifying a task or data flow, &amp; have the messages popping up on a console (in colour for us!) when we&#8217;re running the program manually.</p>
<p>In order to do this, you need to create a project that references Microsoft.SqlServer.ManagedDTS.  After doing that you&#8217;ll need to create a class that&#8217;s derived from Microsoft.SqlServer.Dts.Runtime.LogProviderBase, as shown below:</p>
<pre class="brush: csharp;">
[System.Diagnostics.CodeAnalysis.SuppressMessage(&quot;Microsoft.Naming&quot;, &quot;CA1724:TypeNamesShouldNotMatchNamespaces&quot;), System.Diagnostics.CodeAnalysis.SuppressMessage(&quot;Microsoft.Design&quot;, &quot;CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable&quot;),
 DtsLogProvider(DisplayName = &quot;SSISLogProvider&quot;, Description = &quot;Writes log entries for events to an alternative log provider&quot;, LogProviderType = &quot;Custom&quot;)]
class SSISLogProvider : LogProviderBase
{
    protected ILog _Log = LogManager.GetLogger(&quot;SSIS&quot;);

    public override void OpenLog()
    {
        _Log.Debug(&quot;Opening logger&quot;);
    }

    public override void Log(string logEntryName, string computerName, string operatorName, string sourceName, string sourceID, string executionID, string messageText, DateTime startTime, DateTime endTime, int dataCode, byte[] dataBytes)
    {

        if (!string.IsNullOrEmpty(messageText))
        {
            string logMessage = string.Format(&quot;{0}: {1} ({2})&quot;, sourceName, messageText, logEntryName);
            switch (logEntryName)
            {
                case &quot;OnPreExecute&quot;:
                case &quot;OnPostExecute&quot;:
                case &quot;OnPreValidate&quot;:
                case &quot;OnPostValidate&quot;:
                    _Log.Debug(logMessage);
                    break;
                case &quot;OnWarning&quot;:
                    _Log.Warn(logMessage);
                    break;
                case &quot;OnError&quot;:
                    _Log.Error(logMessage);
                    break;
                default:
                    _Log.Info(logMessage);
                    break;
            }
        }
    }

    public override void CloseLog()
    {
        _Log.Debug(&quot;Closing logger&quot;);
    }

    public override DTSExecResult Validate(IDTSInfoEvents events)
    {
        _Log.Debug(&quot;Validating&quot;);
        return DTSExecResult.Success;
    }
}
</pre>
<p>This does look like a bit of a convoluted class, but it&#8217;s quite simple to explain.  Error messages are sent to the error level, warnings are sent to the warning level, pre &amp; post execution, validation &amp; logger opening / closing messages are sent to the debug level and everything else is sent to info.  That way you don&#8217;t have junk messages in your logs unless you really need them.</p>
<p>So how do you use this from your C# program?  Well, here&#8217;s a simple console application that uses Log4Net &#8211; it&#8217;s easy enough to move over to Commons Logging:</p>
<pre class="brush: csharp;">
class Program
{
    static void Main(string[] args)
    {
        log4net.Config.XmlConfigurator.Configure();
        Application app = new Application();

        Package package = app.LoadPackage(&quot;mypackage.dtsx&quot;, null);

        package.LoggingOptions.EventFilterKind = DTSEventFilterKind.Inclusion;
        LogProvider log = package.LogProviders.Add(typeof(SSISLogProvider).AssemblyQualifiedName);
        package.LoggingOptions.SelectedLogProviders.Add(log);
        package.LoggingMode = DTSLoggingMode.Enabled;

        package.Execute();
    }
}
</pre>
<p>And that is pretty much all there is to it!  You can provide other details such as passwords via the instance of Package.  The only other thing to do is set app.config up for your log provider.  If there&#8217;s enough demand I&#8217;ll add a sample program with a very simple sample package for you to play with.</p>
<p>Happy logging!</p>
<p>*I am aware that in SSIS 2008, you can write tasks in C# &#8211; unfortunately I was restricted to the 2005 version.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simonrice.com/blog/2010/02/14/log4ssis/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>First post (of many hopefully)</title>
		<link>http://www.simonrice.com/blog/2010/02/14/hello-world/</link>
		<comments>http://www.simonrice.com/blog/2010/02/14/hello-world/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 17:58:32 +0000</pubDate>
		<dc:creator>Simon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.simonrice.com/blog/?p=1</guid>
		<description><![CDATA[I&#8217;ve finally joined the professional blogging bandwagon.  Indeed this is the first time I&#8217;ve set up a website under my own name, so it&#8217;s all quite exciting.
So who am I?  Well, my name is Simon Rice &#38; I&#8217;m a programmer from London.  Over the past few years I&#8217;ve been learning how to program under a [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve finally joined the professional blogging bandwagon.  Indeed this is the first time I&#8217;ve set up a website under my own name, so it&#8217;s all quite exciting.</p>
<p>So who am I?  Well, my name is Simon Rice &amp; I&#8217;m a programmer from London.  Over the past few years I&#8217;ve been learning how to program under a number of environments from C under Linux to Java under Windows to Objective-C under Mac OSX.  My current job is a .NET development role, so most of the posts you&#8217;ll be seeing are .NET oriented, although I hope to have more generalist ideas here as well.</p>
<p>At least for the time being, the idea of this blog will be to post snippets &amp; how-tos that I believe haven&#8217;t been posted anywhere else online &amp; may hopefully come in useful to at least one other developer out there.  They&#8217;ll generally be answers to my own questions that I haven&#8217;t raised on developer forums like <a href="http://www.stackoverflow.com/" target="_blank">Stack Overflow</a>.</p>
<p>I&#8217;m no expert of software licensing at the moment, so I&#8217;ve decided for the time being I should put all the code you see here out on a &#8220;credit where it&#8217;s due&#8221; licence.  That is, I don&#8217;t mind if you adapt, modify, improve, or even make it worse &#8211; all I ask is you give credit to me for any ideas I raise &amp; possibly a link to this website.</p>
<p>Anyway, I have a few posts lined up &amp; touch wood the first will be coming up very soon, so I hope you find everything here informative.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simonrice.com/blog/2010/02/14/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

