<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>Where's Lou</title>
	
	<link>http://whereslou.com</link>
	<description>It works on my machine</description>
	<pubDate>Mon, 04 Jan 2010 06:43:56 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/WheresLou" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="whereslou" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Extending NHibernate data with one-to-optional relationships</title>
		<link>http://whereslou.com/2010/01/03/extending-nhibernate-data-with-one-to-optional-relationships</link>
		<comments>http://whereslou.com/2010/01/03/extending-nhibernate-data-with-one-to-optional-relationships#comments</comments>
		<pubDate>Mon, 04 Jan 2010 01:51:43 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[tech]]></category>

		<category><![CDATA[nhibernate]]></category>

		<category><![CDATA[orm]]></category>

		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=684</guid>
		<description><![CDATA[It&#8217;s been said that ninety percent of the time you think there is a one-to-one relationship in NHibernate it&#8217;s really a many-to-one. I&#8217;ll agree with that. But this post is about one of the ten-percent cases when a single entity spans several table schemas.
So the scenario is one where you have a thing that can [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.jagregory.com/2009/01/27/i-think-you-mean-a-many-to-one-sir/">It&#8217;s been said</a> that ninety percent of the time you think there is a one-to-one relationship in NHibernate it&#8217;s really a many-to-one. I&#8217;ll agree with that. But this post is about one of the ten-percent cases when a single entity spans several table schemas.</p>
<p>So the scenario is one where you have a thing that can be extended with additional data. And capabilities, of course, but this post is just about the data. In a traditional app it&#8217;s very straightforward to add additional fields when a new feature is added.<br />
<span id="more-684"></span><br />
Consider a thing with foo and bar fields, before:</p>
<p><img src="http://whereslou.com/wp-content/uploads/2010/01/original-row.png" alt="original-row" title="original-row" width="193" height="101" class="alignnone size-full wp-image-685" /></p>
<p>And adding the thing with frap and quad fields, after:</p>
<p><img src="http://whereslou.com/wp-content/uploads/2010/01/original-extended.png" alt="original-extended" title="original-extended" width="321" height="101" class="alignnone size-full wp-image-686" /></p>
<p>This might not be the best way to go in a dynamic system. If the feature was strictly optional some users wouldn&#8217;t choose to activate it at all, so adding columns to a core table would be bad. Maybe not all of the things in the system would use the frap-quad fields, so having a very large number of (null) fields could be nice to avoid. In those cases a vertical data partition could be a nice approach.</p>
<p><img src="http://whereslou.com/wp-content/uploads/2010/01/vertical-partition1.png" alt="vertical-partition" title="vertical-partition" width="454" height="101" class="alignnone size-full wp-image-688" /></p>
<p>In fact let&#8217;s go the extra step and make a core Thing record, with a ThingType, and move the foo and bar fields onto their own vertical record partition.</p>
<p><img src="http://whereslou.com/wp-content/uploads/2010/01/vertical-partition-with-type.png" alt="vertical-partition-with-type" title="vertical-partition-with-type" width="454" height="221" class="alignnone size-full wp-image-692" /></p>
<p>Now that&#8217;s starting to look a bit crazy, but that&#8217;s really the split-up view of a single logical entity. The goal behind breaking them apart is to have Frappable and FooBar aspects mutually ignorant of each other. In the end the logical view of entity #6 is still just the following:</p>
<p><img src="http://whereslou.com/wp-content/uploads/2010/01/logical-view-with-type.png" alt="logical-view-with-type" title="logical-view-with-type" width="397" height="141" class="alignnone size-full wp-image-694" /></p>
<p>Now let&#8217;s wire that together with some data <a href="http://nhforge.org/">NHibernate</a> classes and <a href="http://fluentnhibernate.org/">Fluent NHibernate</a>.</p>
<pre class="brush: csharp;">
public class ThingType {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

public class Thing {
    public virtual int Id { get; set; }
    public virtual ThingType ThingType { get; set; }
}

public class FooBar {
    public virtual int Id { get; set; }
    public virtual Thing Thing { get; set; }
    public virtual string Foo { get; set; }
    public virtual string Bar { get; set; }
}

public class Frappable {
    public virtual int Id { get; set; }
    public virtual Thing Thing { get; set; }
    public virtual string Frap { get; set; }
    public virtual string Quad { get; set; }
}
</pre>
<p>As a quick sample let&#8217;s use a console app to create and populate a database.</p>
<pre class="brush: csharp;">
static void Main(string[] args) {
    var database = SQLiteConfiguration.Standard.UsingFile(&quot;DataSample.db&quot;).ShowSql();
    var model = AutoMap.Assembly(typeof(Thing).Assembly);

    var sessionFactory = Fluently.Configure()
        .Database(database)
        .Mappings(mappings =&gt; mappings.AutoMappings.Add(model))
        .ExposeConfiguration(config =&gt; new SchemaExport(config).Execute(false, true, false))
        .BuildSessionFactory();

    Console.WriteLine(&quot;Adding records&quot;);
    var session = sessionFactory.OpenSession();
    var fooType = new ThingType { Name = &quot;foo&quot; };
    var fooPlusType = new ThingType { Name = &quot;fooplus&quot; };

    var thing = new Thing { ThingType = fooPlusType };
    var fooBar = new FooBar { Thing = thing, Foo = &quot;brillig&quot;, Bar = &quot;slithe&quot; };
    var frappable = new Frappable { Thing = thing, Frap = &quot;did&quot;, Quad = &quot;and&quot; };

    session.Save(fooType);
    session.Save(fooPlusType);
    session.Save(thing);
    session.Save(fooBar);
    session.Save(frappable);
    session.Close();

    Console.WriteLine(&quot;Fetching thing #{0}&quot;, thing.Id);
    session = sessionFactory.OpenSession();
    var fetch = session.Get&lt;Thing&gt;(thing.Id);
    Console.WriteLine(fetch.ThingType.Name);
    session.Close();
}
</pre>
<p>And the console output is this</p>
<pre class="brush: text;">
Adding records
NHibernate: INSERT INTO &quot;ThingType&quot; (Name) VALUES (@p0); select last_insert_rowid();@p0 = 'foo'
NHibernate: INSERT INTO &quot;ThingType&quot; (Name) VALUES (@p0); select last_insert_rowid();@p0 = 'fooplus'
NHibernate: INSERT INTO &quot;Thing&quot; (ThingType_id) VALUES (@p0); select last_insert_rowid();@p0 = 2
NHibernate: INSERT INTO &quot;FooBar&quot; (Foo, Bar, Thing_id) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 'brillig', @p1 = 'slithe', @p2 = 1
NHibernate: INSERT INTO &quot;Frappable&quot; (Frap, Quad, Thing_id) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 'did', @p1 = 'and', @p2 = 1
Fetching thing #1
NHibernate: SELECT thing0_.Id as Id1_0_, thing0_.ThingType_id as ThingType2_1_0_ FROM &quot;Thing&quot; thing0_ WHERE thing0_.Id=@p0;@p0 = 1
NHibernate: SELECT thingtype0_.Id as Id0_0_, thingtype0_.Name as Name0_0_ FROM &quot;ThingType&quot; thingtype0_ WHERE thingtype0_.Id=@p0;@p0 = 2
fooplus
Press any key to continue . . .
</pre>
<p>As expected so far it&#8217;s not really a one-to-zero-or-one relationship. The FooBar.Id is an identity column generated by the table instead of copied from Thing.Id, and there really shouldn&#8217;t be a FooBar.Thing_id column at all. Let&#8217;s update that with an automapping alteration&#8230;</p>
<pre class="brush: csharp;">
class Alteration : IAutoMappingAlteration {
    public void Alter(AutoPersistenceModel model) {
        model.Override&lt;FooBar&gt;(map =&gt; {
            map.Id(x =&gt; x.Id).GeneratedBy.Foreign(&quot;Thing&quot;);
            map.HasOne(x =&gt; x.Thing).Constrained();
        });
        model.Override&lt;Frappable&gt;(map =&gt; {
            map.Id(x =&gt; x.Id).GeneratedBy.Foreign(&quot;Thing&quot;);
            map.HasOne(x =&gt; x.Thing).Constrained();
        });
    }
}
// and in the main() method
    var model = AutoMap.Assembly(typeof(Program).Assembly)
        .Alterations(alt =&gt; alt.Add(new Alteration()));
</pre>
<p>And the console output is now:</p>
<pre class="brush: text;">
Adding records
NHibernate: INSERT INTO &quot;ThingType&quot; (Name) VALUES (@p0); select last_insert_rowid();@p0 = 'foo'
NHibernate: INSERT INTO &quot;ThingType&quot; (Name) VALUES (@p0); select last_insert_rowid();@p0 = 'fooplus'
NHibernate: INSERT INTO &quot;Thing&quot; (ThingType_id) VALUES (@p0); select last_insert_rowid();@p0 = 2
NHibernate: INSERT INTO &quot;FooBar&quot; (Foo, Bar, Id) VALUES (@p0, @p1, @p2);@p0 = 'brillig', @p1 = 'slithe', @p2 = 1
NHibernate: INSERT INTO &quot;Frappable&quot; (Frap, Quad, Id) VALUES (@p0, @p1, @p2);@p0 = 'did', @p1 = 'and', @p2 = 1
Fetching thing #1
NHibernate: SELECT thing0_.Id as Id1_0_, thing0_.ThingType_id as ThingType2_1_0_ FROM &quot;Thing&quot; thing0_ WHERE thing0_.Id=@p0;@p0 = 1
NHibernate: SELECT thingtype0_.Id as Id0_0_, thingtype0_.Name as Name0_0_ FROM &quot;ThingType&quot; thingtype0_ WHERE thingtype0_.Id=@p0;@p0 = 2
fooplus
Press any key to continue . . .
</pre>
<p>That&#8217;s closer to what we&#8217;re looking for. Note the FooBar.Id is an inserted field now where it&#8217;s value comes from the Thing property, and the Thing_id column is gone from the schema.</p>
<p>The Id/Thing pair and override become cut-and-paste noise pretty quickly though, so we can factor those into an abstract base class and even make the HasOne alteration work on all data classes descended from it. Like this:</p>
<pre class="brush: csharp;">
public abstract class ThingPart {
    public virtual int Id { get; set; }
    public virtual Thing Thing { get; set; }
}

class Alteration : IAutoMappingAlteration {
    public void Alter(AutoPersistenceModel model) {
        model.OverrideAll(map =&gt; {
            var recordType = map.GetType().GetGenericArguments().Single();
            if (recordType.IsAssignableFrom(typeof(ThingPart))) {
                var changeType = typeof(Change&lt;&gt;).MakeGenericType(recordType);
                var change = (IChange)Activator.CreateInstance(changeType);
                change.Go(map);
            }
        });
    }

    interface IChange {
        void Go(object mapObject);
    }

    class Change&lt;TRecord&gt; : IChange where TRecord : ThingPart {
        void IChange.Go(object mapObject) {
            var map = (AutoMapping&lt;TRecord&gt;)mapObject;
            map.Id(x =&gt; x.Id).GeneratedBy.Foreign(&quot;Thing&quot;);
            map.HasOne(x =&gt; x.Thing).Constrained();
        }
    }
}
</pre>
<p>There! In the end the following is all you need for an extension to add a new handful of fields onto thing.</p>
<pre class="brush: csharp;">
public class FooBar : ThingPart {
    public virtual string Foo { get; set; }
    public virtual string Bar { get; set; }
}

public class Frappable : ThingPart {
    public virtual string Frap { get; set; }
    public virtual string Quad { get; set; }
}
</pre>
<p>There are some more tricks you need to query across several parts at once, but that&#8217;s probably another blog post on it&#8217;s own.</p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/F61h4dwposY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2010/01/03/extending-nhibernate-data-with-one-to-optional-relationships/feed</wfw:commentRss>
		</item>
		<item>
		<title>Spark in the Field - Fancy Dress Outfitters</title>
		<link>http://whereslou.com/2009/11/14/spark-in-the-field-fancy-dress-outfitters</link>
		<comments>http://whereslou.com/2009/11/14/spark-in-the-field-fancy-dress-outfitters#comments</comments>
		<pubDate>Sun, 15 Nov 2009 04:36:07 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[spark]]></category>

		<category><![CDATA[internet]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=677</guid>
		<description><![CDATA[ This post is really far overdue - I&#8217;ve been pretty busy. This site has been live for quite a while, over a month now at least? The first I heard of this site was when Howard van Rooijen sent a message to the Spark dev group.
In the thread Howard says, among other things:

For those [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.fancydressoutfitters.co.uk/"><img src="http://whereslou.com/wp-content/uploads/2009/11/fancydressoutfitters.png" alt="fancydressoutfitters" title="fancydressoutfitters" width="363" height="74" class="alignright size-full wp-image-678" /></a> This post is really far overdue - I&#8217;ve been pretty busy. This site has been live for quite a while, over a month now at least? The first I heard of this site was when <a href="http://consultingblogs.emc.com/howardvanrooijen/">Howard van Rooijen</a> sent <a href="http://groups.google.com/group/spark-dev/browse_thread/thread/5626320be23076a3/e895a9c299938fd2">a message to the Spark dev group</a>.</p>
<p>In the thread Howard says, among other things:</p>
<blockquote><p>
For those who are interested - here&#8217;s a little more info:</p>
<p>- We ran the project using Scrum and delivered in 20 weeks: 10 x 2 week iterations<br />
- It&#8217;s based on the S#arp Architecture <http://www.sharparchitecture.net/>framework, which we extended to support Spark and ViewModels<br />
- Integrated other OSS projects into the solution the one most relevant to Spark being N2CMS <http://n2cms.com/><br />
- Solution performs very well: 1000 concurrent users per web server, generating around 180 pages per second across 2x single quad core 64bit servers.<br />
- The site has a YSlow B Grading.
</p></blockquote>
<p>Very nice. His associate <a href="http://consultingblogs.emc.com/jamesbroome/default.aspx">James Broome</a> also has a post talking about their project as it relates to <a href="http://consultingblogs.emc.com/jamesbroome/archive/2009/08/24/asp-net-mvc-separation-of-concerns-amongst-team-members.aspx">Asp.Net MVC – Separation of concerns amongst team members</a>. You&#8217;ve gotta love hearing real-world examples of where UI-centric concerns and coding-centric concerns can work together in the same space at top speed without stumbling over each other&#8217;s focus.</p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/zGLWVbBdf1U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/11/14/spark-in-the-field-fancy-dress-outfitters/feed</wfw:commentRss>
		</item>
		<item>
		<title>Injecting an ILogger property with Autofac</title>
		<link>http://whereslou.com/2009/10/25/injecting-an-ilogger-property-with-autofac</link>
		<comments>http://whereslou.com/2009/10/25/injecting-an-ilogger-property-with-autofac#comments</comments>
		<pubDate>Mon, 26 Oct 2009 04:39:25 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[autofac]]></category>

		<category><![CDATA[IoC]]></category>

		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=672</guid>
		<description><![CDATA[I&#8217;ve always liked the Castle.Core ILogger and ILoggerFactory abstraction. I don&#8217;t know why but I&#8217;ve never been a fan of log4net so I like to keep direct dependencies to it at arm&#8217;s length.
Looking into Autofac recently, I was trying to find a way of getting a logger property assigned as a component is created from [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve always liked the Castle.Core ILogger and ILoggerFactory abstraction. I don&#8217;t know why but I&#8217;ve never been a fan of log4net so I like to keep direct dependencies to it at arm&#8217;s length.</p>
<p>Looking into <a href="http://code.google.com/p/autofac/">Autofac</a> recently, I was trying to find a way of getting a logger property assigned as a component is created from the container in the same way as <a href="http://www.castleproject.org/container/index.html">Windsor</a>&#8217;s <a href="http://www.castleproject.org/container/facilities/trunk/logging/index.html">logging facility</a>. The Autofac container has a <a href="http://code.google.com/p/autofac/wiki/StructuringWithModules">Module/IModule</a> extensibility which works well for the tasks a facility would have done.</p>
<p>Here&#8217;s the type of code I&#8217;m used to seeing from logging. </p>
<pre class="brush: csharp;">
using Castle.Core.Logging;

namespace LoggingStudy {
    public interface IFoo {
        void Bar();
    }

    public class Foo : IFoo {
        public Foo() {
            Logger = NullLogger.Instance;
        }

        public ILogger Logger { get; set; }

        public void Bar() {
            Logger.Info(&quot;Bar called&quot;);
        }
    }
}
</pre>
<p><span id="more-672"></span><br />
And here&#8217;s how you&#8217;d add a logging module to an Autofac builder.</p>
<pre class="brush: csharp;">
using Autofac.Builder;

namespace LoggingStudy {

    class Program {
        static void Main(string[] args) {
            var builder = new ContainerBuilder();
            builder.RegisterModule(new LoggingModule());
            builder.Register&lt;Foo&gt;().As&lt;IFoo&gt;();

            var container = builder.Build();

            using (var scope = container.CreateInnerContainer()) {
                var foo = scope.Resolve&lt;IFoo&gt;();
                foo.Bar();
            }
        }
    }
}
</pre>
<p>And here&#8217;s an implementation of a LoggingModule that will use Castle&#8217;s ILoggerFactory to assign the ILogger typed public properties. Some of the code is based on a few threads in the discussion group.</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Builder;
using Castle.Core.Logging;

namespace LoggingStudy {
    public class LoggingModule : Autofac.Builder.Module {
        protected override void Load(ContainerBuilder moduleBuilder) {
            // by default, use Castle's TraceSource based logger factory
            moduleBuilder.Register&lt;TraceLoggerFactory&gt;().As&lt;ILoggerFactory&gt;().ContainerScoped();

            // call CreateLogger in response to the request for an ILogger implementation
            moduleBuilder.Register((ctx, ps) =&gt; CreateLogger(ctx, ps)).As&lt;ILogger&gt;().FactoryScoped();
        }

        protected override void AttachToComponentRegistration(IContainer container, IComponentRegistration registration) {
            var implementationType = registration.Descriptor.BestKnownImplementationType;

            // build an array of actions on this type to assign loggers to member properties
            var injectors = BuildLoggerInjectors(implementationType).ToArray();

            // if there are no logger properties, there's no reason to hook the activated event
            if (!injectors.Any())
                return;

            // otherwise, whan an instance of this component is activated, inject the loggers on the instance
            registration.Activated += (s, e) =&gt; {
                foreach (var injector in injectors)
                    injector(e.Context, e.Instance);
            };
        }

        private static IEnumerable&lt;Action&lt;IContext, object&gt;&gt; BuildLoggerInjectors(Type componentType) {
            // Look for settable properties of type &quot;ILogger&quot;
            var loggerProperties = componentType
                .GetProperties(BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance)
                .Select(p =&gt; new {
                    PropertyInfo = p,
                    p.PropertyType,
                    IndexParameters = p.GetIndexParameters(),
                    Accessors = p.GetAccessors(false)
                })
                .Where(x =&gt; x.PropertyType == typeof(ILogger)) // must be a logger
                .Where(x =&gt; x.IndexParameters.Count() == 0) // must not be an indexer
                .Where(x =&gt; x.Accessors.Length != 1 || x.Accessors[0].ReturnType == typeof(void)); //must have get/set, or only set

            // Return an array of actions that resolve a logger and assign the property
            foreach (var entry in loggerProperties) {
                var propertyInfo = entry.PropertyInfo;

                yield return (ctx, instance) =&gt; {
                    var propertyValue = ctx.Resolve&lt;ILogger&gt;(new TypedParameter(typeof(Type), componentType));
                    propertyInfo.SetValue(instance, propertyValue, null);
                };
            }
        }

        private static ILogger CreateLogger(IContext context, IEnumerable&lt;Parameter&gt; parameters) {
            // return an ILogger in response to Resolve&lt;ILogger&gt;(componentTypeParameter)
            var loggerFactory = context.Resolve&lt;ILoggerFactory&gt;();
            var containingType = parameters.TypedAs&lt;Type&gt;();
            return loggerFactory.Create(containingType);
        }
    }
}
</pre>
<p>The TraceLoggerFactory is added as a default ILoggerFactory. It&#8217;s my favorite one and because it&#8217;s based on System.Diagnostics TraceSource it doesn&#8217;t require additional assemblies.</p>
<p>If you expect to Resolve<ILogger> from a container you&#8217;ll need to add a TypedParameter for typeof(Type), because the logger factory needs that information. It also doesn&#8217;t work to provide an ILogger constructor parameter as it&#8217;s written, but if ILogger properties are what you&#8217;re looking for it should do the job.</p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/QC-5wUY5D4g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/10/25/injecting-an-ilogger-property-with-autofac/feed</wfw:commentRss>
		</item>
		<item>
		<title>Herding Code podcast about Spark</title>
		<link>http://whereslou.com/2009/09/24/herding-code-podcast-about-spark</link>
		<comments>http://whereslou.com/2009/09/24/herding-code-podcast-about-spark#comments</comments>
		<pubDate>Thu, 24 Sep 2009 18:47:01 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[opensource]]></category>

		<category><![CDATA[spark]]></category>

		<category><![CDATA[geek]]></category>

		<category><![CDATA[podcast]]></category>

		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=668</guid>
		<description><![CDATA[ The Herding Code 60: Spark View Engine with Louis DeJardin podcast just went up. Really fun group of guys. Interesting process they use to record also and seemed to work really well. I can just never get used to the sound of my own voice.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://herdingcode.com/?p=216"><img src="http://whereslou.com/wp-content/uploads/2009/09/herdingcode-165px.png" alt="Herding Code" title="Herding Code" width="165" height="165" class="alignright size-full wp-image-669" /></a> The <a href="http://herdingcode.com/?p=216">Herding Code 60: Spark View Engine with Louis DeJardin</a> podcast just went up. Really fun group of guys. Interesting process they use to record also and seemed to work really well. I can just never get used to the sound of my own voice.</p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/w5htLkqPPog" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/09/24/herding-code-podcast-about-spark/feed</wfw:commentRss>
		</item>
		<item>
		<title>Memory pressure and scale</title>
		<link>http://whereslou.com/2009/09/18/memory-pressure-and-scale</link>
		<comments>http://whereslou.com/2009/09/18/memory-pressure-and-scale#comments</comments>
		<pubDate>Fri, 18 Sep 2009 16:34:44 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[tech]]></category>

		<category><![CDATA[question]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=505</guid>
		<description><![CDATA[This is an open question really for people that make, use, or host ASP.NET apps&#8230; When you&#8217;re choosing a technology stack how important are memory pressure concerns?
So if you&#8217;re looking at adding automapper, or nhiberbate, or ioc xyz, you&#8217;re obviously going to be thinking about impact to CPU and memory.
And there are two type of [...]]]></description>
			<content:encoded><![CDATA[<p>This is an open question really for people that make, use, or host ASP.NET apps&#8230; When you&#8217;re choosing a technology stack how important are memory pressure concerns?</p>
<p>So if you&#8217;re looking at adding automapper, or nhiberbate, or ioc xyz, you&#8217;re obviously going to be thinking about impact to CPU and memory.</p>
<p>And there are two type of memory impacts: load-and-hold and burn-rate (or memory pressure). The first is relatively easy to say you&#8217;re using ten megs of one-time cost memory in each appdomain once it&#8217;s initialized and warmed up. The other&#8217;s a bit more subtle - if a tool goes through a two megs of object, string, collection, buffer memory in a request - and say you&#8217;re tooling along with bursts of 25 req/sec - then 50meg/sec means you&#8217;ve given the garbage collector a gig of ram to recycle every 20 seconds. Numbers and needs vary but you get the idea that high burn rates end up causing a CPU tax to be paid affecting the net power availabe. </p>
<p>But on the other hand dotnet is a high level language, and a lot of there types of things are developer productivity tools - not performance tool - so they will *always* have measurable increase in cost. But in the most extreme cases, like from he point of view of a hosting company, you could almost assume that memory efficiency is directly proportional to hardware, space, and power costs per client&#8230; </p>
<p>Not that it&#8217;s a black and white situation, of course, but at what point are the conveniences and strengths of a library outweighed by the cost of using it? Of course it&#8217;s always difficult to weigh something subjective against something quantifiable. </p>
<p>But what&#8217;s your take on that? </p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/w5zd6twZfmc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/09/18/memory-pressure-and-scale/feed</wfw:commentRss>
		</item>
		<item>
		<title>Building 42</title>
		<link>http://whereslou.com/2009/09/16/building-42</link>
		<comments>http://whereslou.com/2009/09/16/building-42#comments</comments>
		<pubDate>Thu, 17 Sep 2009 02:51:26 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[tech]]></category>

		<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=651</guid>
		<description><![CDATA[ The first blog post was keyed in from a mobile phone before new employee orientation, so I thought I would take a moment to write a more thoughtful post about the first few days. Well, maybe not more thoughtful&#8230; But at least a post that has some links and images in it.
For example, Building [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://whereslou.com/wp-content/uploads/2009/09/ms_net_rgb_web.jpg" alt="ms_net_rgb_web" title="ms_net_rgb_web" width="328" height="80" class="alignright size-full wp-image-656" /> The first blog post was keyed in from a mobile phone before new employee orientation, so I thought I would take a moment to write a more thoughtful post about the first few days. Well, maybe not more thoughtful&#8230; But at least a post that has some links and images in it.</p>
<p>For example, <a href="http://www.bing.com/maps/default.aspx?v=2&#038;FORM=LMLTCP&#038;cp=ry5vpx4tp0cf&#038;style=b&#038;lvl=1&#038;tilt=-90&#038;dir=0&#038;alt=-1000&#038;phx=0&#038;phy=0&#038;phscl=1&#038;scene=3689071&#038;encType=1&#038;cid=B387831F07F582B4!529">Building 42</a>! My new home. I swear walking into the campus this morning I couldn&#8217;t keep the grin off my face.</p>
<p><a href="http://www.bing.com/maps/default.aspx?v=2&#038;FORM=LMLTCP&#038;cp=ry5vpx4tp0cf&#038;style=b&#038;lvl=1&#038;tilt=-90&#038;dir=0&#038;alt=-1000&#038;phx=0&#038;phy=0&#038;phscl=1&#038;scene=3689071&#038;encType=1&#038;cid=B387831F07F582B4!529"><img src="http://whereslou.com/wp-content/uploads/2009/09/building42.png" alt="building42" title="building42" width="478" height="476" class="size-full wp-image-652" /></a></p>
<p>Let&#8217;s see&#8230; What else is there. Ah! There are people in the building! To name a few there&#8217;s <a href="http://weblogs.asp.net/bleroy/archive/2009/08/27/walking-the-tight-rope.aspx">Bertrand Le Roy</a>, Renaud Paquay, Bradley Millington&#8230; Ah, well. I&#8217;m not having much luck finding a public internet presence for a lot of people so I&#8217;ll leave off with the naming of names in case they prefer anonymity. There&#8217;s also people like <a href="http://weblogs.asp.net/scottgu/">Scott Guthrie</a> and <a href="http://haacked.com/">Phil Haack</a> but that would be like pointing out the fact there are roads and trees around the building.</p>
<p>I&#8217;m actually feeling really good about the decision to join Microsoft. Met the team, surrounded by blindingly smart people, workstation fully installed, two beautiful monitors showed up today, getting a handle on where the project is at and where it&#8217;s going. End of the second day and it&#8217;s time to head home now.</p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/2XYC0NMTn98" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/09/16/building-42/feed</wfw:commentRss>
		</item>
		<item>
		<title>Huge changes. Thrilling and stressful</title>
		<link>http://whereslou.com/2009/09/14/huge-changes-thrilling-and-stressful</link>
		<comments>http://whereslou.com/2009/09/14/huge-changes-thrilling-and-stressful#comments</comments>
		<pubDate>Mon, 14 Sep 2009 14:57:36 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[tech]]></category>

		<category><![CDATA[job]]></category>

		<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=647</guid>
		<description><![CDATA[It&#8217;s another one of those self-titled Where&#8217;s Lou posts today! So - where&#8217;s Lou now? New employee orientation in Washington! And Brenda&#8217;s still in Florida at the moment so the DeJardin household is about as geographically distributed as we&#8217;ve ever been. :)
The big news today is I&#8217;ve accepted a position at Microsoft, which is the [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s another one of those self-titled Where&#8217;s Lou posts today! So - where&#8217;s Lou now? New employee orientation in Washington! And Brenda&#8217;s still in Florida at the moment so the DeJardin household is about as geographically distributed as we&#8217;ve ever been. :)</p>
<p>The big news today is I&#8217;ve accepted a position at Microsoft, which is the final realization of an ambition of mine which started a year and a half ago. What hooked me then was watching the open style of development the ASP.NET MVC team was embracing and the great results and positive community feedback they were getting. I though to myself, if there was someplace you could choose to work that would be it.</p>
<p>I should add I&#8217;m not on the MVC team, but since I don&#8217;t know what&#8217;s public knowledge yet or not - please forgive me being vague. </p>
<p>Plus if anyone&#8217;s curious this doesn&#8217;t change the status of Spark regarding license, source, distribution, etc. </p>
<p>But yeah! Exciting! I have to finish up now and grab some coffee and prepare myself for a day of paperwork and hr presentations. Woohoo!  </p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/bsU_hkyN5Tc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/09/14/huge-changes-thrilling-and-stressful/feed</wfw:commentRss>
		</item>
		<item>
		<title>GenCon 2009</title>
		<link>http://whereslou.com/2009/08/13/gencon-2009</link>
		<comments>http://whereslou.com/2009/08/13/gencon-2009#comments</comments>
		<pubDate>Thu, 13 Aug 2009 23:31:54 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[family]]></category>

		<category><![CDATA[gaming]]></category>

		<category><![CDATA[geek]]></category>

		<category><![CDATA[gencon]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=644</guid>
		<description><![CDATA[Where&#8217;s Lou at the moment? Indianapolis! Specifically GenCon 2009.
Today was the first of four days. Played a BattleTech bootcamp with Alex, some nostalgia there for me because that&#8217;s a game I the old group in high school used to play as well. He loved it - we&#8217;re going to be getting the intro box set [...]]]></description>
			<content:encoded><![CDATA[<p>Where&#8217;s Lou at the moment? <a href="http://maps.google.com/maps?q=indianapolis&#038;oe=utf-8&#038;client=firefox-a&#038;ie=UTF8&#038;split=0&#038;gl=us&#038;ei=Up-ESsOzEIniMKqowe4E&#038;z=10&#038;iwloc=A">Indianapolis</a>! Specifically <a href="http://www.gencon.com/2009/indy/default.aspx">GenCon 2009</a>.</p>
<p>Today was the first of four days. Played a <a href="http://en.wikipedia.org/wiki/BattleTech">BattleTech</a> bootcamp with Alex, some nostalgia there for me because that&#8217;s a game I the old group in high school used to play as well. He loved it - we&#8217;re going to be getting the intro box set when we get home.</p>
<p>Also signed up for an interactive action game <a href="http://www.terrorwerks.com/">TerrorWerks</a>. Lots of fun. Three groups of five players armed with the soft yellow pellet assault rifles on an mission in a background that reminds you of the Aliens movies. I was an engineer (or course) and near the end of the mission was severely wounded and out of ammo, and eventually died trying to pull someone back from the end of a corridor where he was bleeding to death. Yay!</p>
<p>Going to run now to and catch an anime &#8220;Berserk&#8221; being screened. :)</p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/e6-UsvKNx4A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/08/13/gencon-2009/feed</wfw:commentRss>
		</item>
		<item>
		<title>Beginning ASP.NET MVC 1.0</title>
		<link>http://whereslou.com/2009/08/10/beginning-aspnet-mvc-10</link>
		<comments>http://whereslou.com/2009/08/10/beginning-aspnet-mvc-10#comments</comments>
		<pubDate>Mon, 10 Aug 2009 18:20:13 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[tech]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<category><![CDATA[books]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[wrox]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=635</guid>
		<description><![CDATA[
I had the opportunity the other day to read through Beginning ASP.NET MVC 1.0 written by Simone Chiaretta and Keyvan Nayyeri. I like how it&#8217;s structured if you may be learning about the concepts from scratch.
The first I had heard about the book was quite a while ago when Simone sent me a few questions [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Beginning-ASP-NET-MVC-Simone-Chiaretta/dp/047043399X/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1249923140&#038;sr=1-1"><img src="http://whereslou.com/wp-content/uploads/2009/08/beginning-aspnet-mvc.jpg" alt="beginning-aspnet-mvc" title="beginning-aspnet-mvc" width="190" height="239" class="alignright size-full wp-image-636" /></a></p>
<p>I had the opportunity the other day to read through <a href="http://www.amazon.com/Beginning-ASP-NET-MVC-Simone-Chiaretta/dp/047043399X/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1249923140&#038;sr=1-1">Beginning ASP.NET MVC 1.0</a> written by <a href="http://codeclimber.net.nz/">Simone Chiaretta</a> and <a href="http://nayyeri.net/">Keyvan Nayyeri</a>. I like how it&#8217;s structured if you may be learning about the concepts from scratch.</p>
<p>The first I had heard about the book was quite a while ago when Simone sent me a few questions about Spark. In the later chapters about extending ASP.NET MVC there&#8217;s a small section that describes various alternate view engines. I have to admit that&#8217;s the first place I flipped to. :)</p>
<p>I especially the fact that after covering the basics early on almost sixty pages are dedicated to unit testing concepts and it&#8217;s implementation for MVC applications. A lot of times in demos and articles even though the importance of testing or TDD is stressed it seems like you don&#8217;t walk away with something actionable if you&#8217;re new to those practices.</p>
<p>Also ends with some real-world samples&#8230; Ah - and all of the code is downloadable from <a href="http://wrox.com">wrox.com</a>. Very nice.</p>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/1Gr8sWpez2Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/08/10/beginning-aspnet-mvc-10/feed</wfw:commentRss>
		</item>
		<item>
		<title>Spark output caching</title>
		<link>http://whereslou.com/2009/07/28/spark-output-caching</link>
		<comments>http://whereslou.com/2009/07/28/spark-output-caching#comments</comments>
		<pubDate>Tue, 28 Jul 2009 19:23:52 +0000</pubDate>
		<dc:creator>Louis</dc:creator>
		
		<category><![CDATA[spark]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<category><![CDATA[caching]]></category>

		<category><![CDATA[internet]]></category>

		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://whereslou.com/?p=617</guid>
		<description><![CDATA[Just finished writing the documentation for the most recent feature added to Spark. It provides output caching for sections of a template that could be costly in terms of rendering or data acquisition.
Part of this comes back to Phil&#8217;s blog post about Donut Hole Caching in ASP.NET MVC. Especially below where he writes, as he&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://whereslou.com/wp-content/uploads/2009/07/scales.png" alt="scales" title="scales" width="320" height="282" class="alignright size-full wp-image-622" />Just finished writing the <a href="http://sparkviewengine.com/documentation/caching">documentation for the most recent feature</a> added to <a href="http://sparkviewengine.com">Spark</a>. It provides output caching for sections of a template that could be costly in terms of rendering or data acquisition.</p>
<p>Part of this comes back to Phil&#8217;s blog post about <a href="http://haacked.com/archive/2009/05/12/donut-hole-caching.aspx">Donut Hole Caching in ASP.NET MVC</a>. Especially below where he writes, as he&#8217;s thinking out loud, &#8220;This would have to work in tandem with some means to specify that the bit of view data intended for the partial view is only recreated when the output cache is expired for that partial view, so we don’t incur the cost of creating it on every request.&#8221;</p>
<p>I have to admit I&#8217;m not necessarily a huge fan of the built-in ASP.NET page caching directives&#8230; Also didn&#8217;t particularly care for the forced alignment of partial-boundaries and cache-boundaries. I would hate to have a larger number of smaller files on disk simply because that&#8217;s the breakdown at which I wanted to cache the individual parts. In an ideal world I would like to be able to quickly and easily mark an expensive bit as cacheable, and provide the caching details that relate specifically to that bit, and be done with it.<br />
<span id="more-617"></span><br />
So - enter Spark caching:</p>
<pre class="brush: xml;">
stuff
&lt;cache key=&quot;employeeId&quot; expires=&quot;300&quot;&gt;
  this is stuff about the employee
&lt;/cache&gt;
stuff
</pre>
<p>Kind of simple, really. The key works like the &lt;%@OutputCache%&gt; VaryByParam value, but it can be a comma delimited csharp expressions of anything which makes the cached information unique. </p>
<p>There&#8217;s a ICacheSignal interface which takes the place of custom CacheDependency classes in the ASP.NET caching framework.</p>
<pre class="brush: xml;">
public interface ICacheSignal
{
    event EventHandler Changed;
}
</pre>
<p>If you want fine-grained control to clear out-of-date cached data you would provide an instance of your implementation of this signal, or you can use the built-in ChangeSignal class. So that could be something as simple as:</p>
<pre class="brush: xml;">
stuff
&lt;cache key=&quot;employeeId&quot; signal=&quot;MyApp.Signals.EmployeeTables&quot;&gt;
  this is stuff about the employee
&lt;/cache&gt;
stuff
</pre>
<pre class="brush: csharp;">
public static class Signals
{
  public static ChangeSignal EmployeeTables = new ChangeSignal();
}
</pre>
<p>You app would need to provide the glue to watch the tables and call <code>Signals.EmployeeTables.FireChanged()</code> of course. It does require a bit more effort, but you&#8217;re free to implement your signaling down to whatever level of granularity you would like. If you cache all of the comment html on a blog post, for example, you could keep a dictionary of change signals per-post-id around to drop exactly the correct amount of cached information when a comment is added or removed.</p>
<p>The implementation was a bit tricky in parts, but it should support the all of the cases where once attributes and named content are used inside or around cache elements.</p>
<p>Ah, yes! Back to the original need for avoiding the cost of gathering view data when the related bit of the view is cached. For that you&#8217;d use a trick with a ValueHolder class which enables you to keep your data acquisition code in the controller&#8217;s action, yet enables a cache hit to avoid the cost of that data acquisition.</p>
<pre class="brush: csharp;">
public ActionResult Details(int id)
{
    var data = new NorthwindDataContext();

    ViewData[&quot;employeeId&quot;] = id;

    ViewData[&quot;employee&quot;] = ValueHolder.For(
        () =&gt; data.Employees.Single(x =&gt; x.EmployeeID == id));

    return View();
}
</pre>
<p>In that case for example you could have a cache key=&#8221;employeeId&#8221; and only use the employee.Value property inside that cache. That way if the html for that section (for that employeeId) has already been created and stored, then the second time through .Value property will never be used and the lambda will never be executed. For example:</p>
<pre class="brush: xml;">
&lt;viewdata employeeId=&quot;int&quot; employee=&quot;ValueHolder[[Employee]]&quot; /&gt;
&lt;cache key=&quot;employeeId&quot;&gt;
  &lt;h3&gt;${employee.Value.FirstName} ${employee.Value.LastName}&lt;/h3&gt;
  this is stuff about employee number ${employee.Value.EmployeeID}.
&lt;/cache&gt;
</pre>
<p>So that&#8217;s a kind of nice way to cut out WCF and SQL costs without violating MVC best practices by having your views fetch data. After all it&#8217;s almost never the rendering costs that are the real problem in the first place.</p>
<p>There&#8217;s also a trick you can use with &lt;viewdata&gt; to get rid of the .Value. when you&#8217;re using the object inside a ValueHolder.</p>
<pre class="brush: xml;">
&lt;viewdata employeeId=&quot;int&quot; employee.Value=&quot;Employee employee&quot; /&gt;
&lt;cache key=&quot;employeeId&quot;&gt;
  &lt;h3&gt;${employee.FirstName} ${employee.LastName}&lt;/h3&gt;
  this is stuff about employee number ${employee.EmployeeID}.
&lt;/cache&gt;
</pre>
<p><ins datetime="2009-07-29T15:06:59+00:00">Updated, in answer to Adam&#8217;s question in the comments</ins></p>
<p>A value holder can also by used inside of a strongly typed model, like this.</p>
<pre class="brush: csharp;">
public class EmployeeDetailsModel
{
    // lazy-loaded data
    public ValueHolder&lt;int, Employee&gt; EmployeeHolder {get;set;}

    // aliasing .Key and .Value
    public int EmployeeID {get {return EmployeeHolder.Key;} }
    public Employee Employee {get {return EmployeeHolder.Value;} }
}

public ActionResult Details(int id)
{
    var data = new NorthwindDataContext();

    var model = new EmployeeDetailsModel
    {
        EmployeeHolder = ValueHolder.For(id,
            key =&gt; data.Employees.Single(x =&gt; x.EmployeeID == key))
    };

    return View(model);
}
</pre>
<p>And the usage in the view is about what you would expect.</p>
<pre class="brush: xml;">
&lt;viewdata model=&quot;EmployeeDetailsModel&quot; /&gt;
&lt;cache key=&quot;Model.EmployeeID&quot;&gt;
  &lt;h3&gt;${Model.Employee.FirstName} ${Model.Employee.LastName}&lt;/h3&gt;
  this is stuff about employee number ${Model.Employee.EmployeeID}.
&lt;/cache&gt;
</pre>
<img src="http://feeds.feedburner.com/~r/WheresLou/~4/tN3lEzgdu6I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://whereslou.com/2009/07/28/spark-output-caching/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
