<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>marklio</title>
    <link>http://www.marklio.com/marklio/</link>
    <description>better than the original</description>
    <image>
      <url>http://photos1.flickr.com/buddyicons/12488026@N00.jpg?1105565509</url>
      <title>marklio</title>
      <link>http://www.marklio.com/marklio/</link>
    </image>
    <language>en-us</language>
    <copyright>Mark Miller</copyright>
    <lastBuildDate>Fri, 20 Jun 2008 21:05:13 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>mark@marklio.com</managingEditor>
    <webMaster>mark@marklio.com</webMaster>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f</wfw:commentRss>
      <title>LinqToStdf now on CodePlex</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f.aspx</link>
      <pubDate>Fri, 20 Jun 2008 21:05:13 GMT</pubDate>
      <description>&lt;p&gt;
Some of my posts that I get the most recurring email/inquiries on are my &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f&amp;amp;url=http%3a%2f%2fwww.marklio.com%2fmarklio%2fPermaLink%2cguid%2c3a89ecce-89a8-470e-a894-bc5cc86ce41d.aspx"" target="_blank"&gt;various&lt;/a&gt; &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f&amp;amp;url=http%3a%2f%2fwww.marklio.com%2fmarklio%2fPermaLink%2cguid%2c498e2e35-1590-4852-92e1-2212157c68f1.aspx"" target="_blank"&gt;posts&lt;/a&gt; about
the STDF (Standard Test Datalog Format) parser that I &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f&amp;amp;url=http%3a%2f%2fwww.marklio.com%2fmarklio%2fPermaLink%2cguid%2ce3601f31-231b-4a82-b5a7-1c31600ce25c.aspx"" target="_blank"&gt;originally
created as an experiment back in 2005&lt;/a&gt;.&amp;nbsp; After some help from a former collegue,
I am pleased to announce that this is finally available on CodePlex as &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f&amp;amp;url=http%3a%2f%2fwww.codeplex.com%2fLinqToStdf"" target="_blank"&gt;LinqToStdf&lt;/a&gt;!
&lt;/p&gt;
&lt;p&gt;
It is a managed library for processing STDF files, and gives you a model to explore
the data via Linq queries.&amp;nbsp; This means, you can leverage the wide variety of
managed languages (C#, VB, F#, JScript, IronPython, IronRuby, Managed C++, Boo, &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f&amp;amp;url=http%3a%2f%2fwww.dotnetlanguages.net%2fDNL%2fResources.aspx"" target="_blank"&gt;etc&lt;/a&gt;.)
to process the data in STDF files.&amp;nbsp; It also works in &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f&amp;amp;url=http%3a%2f%2fsilverlight.net"" target="_blank"&gt;Silverlight&lt;/a&gt;!&amp;nbsp;
It has built-in support for the V4 spec, but it's highly extensible and should be
able to parse any version of the file format as well as custom records.&amp;nbsp; It can
be configured to be highly strict and throw on format errors, or be robust in the
face of issues that normal STDF processors would choke on to the point of being able
to detect and repair corruption on the fly.
&lt;/p&gt;
&lt;p&gt;
If that interests you, I'd love for you to drop by and take a deeper look at it and
get involved in its ongoing development.&amp;nbsp; I've already got at least one person
interested enough to contribute and ensure its success as a community project.&amp;nbsp;
There is currently a &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f&amp;amp;url=http%3a%2f%2fwww.codeplex.com%2fLinqToStdf%2fRelease%2fProjectReleases.aspx%3fReleaseId%3d13681"" target="_blank"&gt;"beta"
release&lt;/a&gt; available, and hopefully we'll whip it into shape enough to call it v1.0
soon.
&lt;/p&gt;
&lt;p&gt;
My hope is that this can be an adoption driver for .NET in the semiconductor industry
and that through this project I can be an ambassador for the CLR in that area.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,45b930b6-bfd0-4aeb-9bb8-1e82b2ff9e5f.aspx</comments>
      <category>Announcements;Fun;Software Development</category>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=f5216e74-ce9f-4b7a-b1de-157ea51bf987</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,f5216e74-ce9f-4b7a-b1de-157ea51bf987.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,f5216e74-ce9f-4b7a-b1de-157ea51bf987.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=f5216e74-ce9f-4b7a-b1de-157ea51bf987</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <title>Image Slicer for Deep Zoom in Silverlight 2</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,f5216e74-ce9f-4b7a-b1de-157ea51bf987.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,f5216e74-ce9f-4b7a-b1de-157ea51bf987.aspx</link>
      <pubDate>Wed, 11 Jun 2008 06:01:35 GMT</pubDate>
      <description>&lt;p&gt;
I've been playing alot with beta 2 of &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=f5216e74-ce9f-4b7a-b1de-157ea51bf987&amp;amp;url=http%3a%2f%2fsilverlight.net"" target="_blank"&gt;Silverlight&lt;/a&gt; 2,
and I've been totally amazed at the scenarios it enables.&amp;nbsp; Working hard down
inside the CLR engine, we're sometimes insulated from some of the innovation going
on higher in the stack and it blows us away when we do get a chance to see it.
&lt;/p&gt;
&lt;p&gt;
One of the very cool things in Silverlight is "&lt;a href="http://www.marklio.com/marklio/ct.ashx?id=f5216e74-ce9f-4b7a-b1de-157ea51bf987&amp;amp;url=http%3a%2f%2fblogs.msdn.com%2fexpression%2farchive%2f2008%2f06%2f07%2fwhat-s-new-in-deep-zoom-composer.aspx"" target="_blank"&gt;Deep
Zoom&lt;/a&gt;", which came from the &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=f5216e74-ce9f-4b7a-b1de-157ea51bf987&amp;amp;url=http%3a%2f%2flabs.live.com%2fSeadragon.aspx"" target="_blank"&gt;SeaDragon&lt;/a&gt; project
from Microsoft Research.&amp;nbsp; I decided to try it out myself on a very large panorama
that I made a long time ago in New Orleans.&amp;nbsp; Unfortunately, the current toolset
seems to trip over the large file size (20516x15291).&amp;nbsp; I'm trying to find out
the real story behind the limitation.&amp;nbsp; All I know right now is that smaller files
work.
&lt;/p&gt;
&lt;p&gt;
So, I decided to try to slice it up into smaller, manageable chunks and just butt
them against one another to simulate one large file.&amp;nbsp; The problem was that I
couldn't find a tool to do this that didn't also trip up over the size of the file.&amp;nbsp;
So, I wrote my own.&amp;nbsp; There are likely better ways to do this, this was just a
quick and dirty attempt to make something that didn't totally crawl to a halt due
to page faulting (or outright throw OutOfMemoryException).
&lt;/p&gt;
&lt;p&gt;
The code below is what I came up with.&amp;nbsp; I use &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=f5216e74-ce9f-4b7a-b1de-157ea51bf987&amp;amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fsystem.drawing.bitmap.aspx"" target="_blank"&gt;System.Drawing.Bitmap&lt;/a&gt;,
lock the portions of the image I need, and do the data copying myself.&amp;nbsp; I ended
up with this solution because GDI+ (&lt;a href="http://www.marklio.com/marklio/ct.ashx?id=f5216e74-ce9f-4b7a-b1de-157ea51bf987&amp;amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fsystem.drawing.graphics.drawimage.aspx"" target="_blank"&gt;DrawImage&lt;/a&gt;)
seems to like to make alot of buffers (big ones in this case), and I couldn't fall
back on good ol' &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=f5216e74-ce9f-4b7a-b1de-157ea51bf987&amp;amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fms532278(VS.85).aspx"" target="_blank"&gt;bitblt&lt;/a&gt; because
I couldn't get the right kind of data structures without more copying of the data.&amp;nbsp;
This runs plenty fast and only takes up marginally more memory than it takes to represent
the original and the size of one of the destination tiles.
&lt;/p&gt;
&lt;p&gt;
Unfortunately, The &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=f5216e74-ce9f-4b7a-b1de-157ea51bf987&amp;amp;url=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fsystem.windows.controls.multiscaleimage(VS.95).aspx"" target="_blank"&gt;MultiScaleImage&lt;/a&gt; does
some weirdness with image that are butted up against each other, and you get as much
as a whole pixel of "space" between them, depending on your zoom level. I'm still
looking into other possible workarounds. So, it's wasn't ultimately useful, but I
thought the code was interesting enough, and probably has academic usefulness.&amp;nbsp;
So, enough talk, here's the code:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Drawing;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Drawing.Imaging;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.InteropServices;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; ImageSlicer
{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Extensions
{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt;
Times(&lt;span class="kwrd"&gt;this&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; number) {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; &lt;span class="kwrd"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt;
number; i++) &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; i;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Program {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; [DllImport(&lt;span class="str"&gt;"msvcrt.dll"&lt;/span&gt;,
SetLastError = &lt;span class="kwrd"&gt;false&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;unsafe&lt;/span&gt; &lt;span class="kwrd"&gt;extern&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;*
memcpy(&lt;span class="kwrd"&gt;byte&lt;/span&gt;* dest, &lt;span class="kwrd"&gt;byte&lt;/span&gt;* src, &lt;span class="kwrd"&gt;int&lt;/span&gt; count);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[]
args) {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; var sourcePath = args.FirstOrDefault();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (String.IsNullOrEmpty(sourcePath))
{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"No
source image path provided"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt; ShowUsage();&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 25: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 26: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 27: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (!File.Exists(sourcePath))
{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 28: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Source image
path doesn't exist"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 29: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 30: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 31: &lt;/span&gt; var gridSizeStr = args.Skip(1).FirstOrDefault();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 32: &lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; gridSize = 4;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 33: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (gridSizeStr
!= &lt;span class="kwrd"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; !&lt;span class="kwrd"&gt;int&lt;/span&gt;.TryParse(gridSizeStr, &lt;span class="kwrd"&gt;out&lt;/span&gt; gridSize))
{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 34: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Could not
convert {0} to a valid grid size"&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 35: &lt;/span&gt; gridSizeStr);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 36: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 37: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 38: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (gridSize &amp;lt; 2)
{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 39: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"The
grid size must be greater than 1."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 40: &lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 41: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 42: &lt;/span&gt; &lt;span class="kwrd"&gt;try&lt;/span&gt; {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 43: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Slicing
{0} into a {1}x{1} grid."&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 44: &lt;/span&gt; Path.GetFileName(sourcePath), gridSize);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 45: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Loading..."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 46: &lt;/span&gt; &lt;span class="kwrd"&gt;using&lt;/span&gt; (var sourceBitmap
= &lt;span class="kwrd"&gt;new&lt;/span&gt; Bitmap(sourcePath)) {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 47: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Source
Image: {0}x{1}"&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 48: &lt;/span&gt; sourceBitmap.Width, sourceBitmap.Height);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 49: &lt;/span&gt; var sliceWidth = sourceBitmap.Width
/ gridSize;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 50: &lt;/span&gt; var sliceHeight = sourceBitmap.Height / gridSize;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 51: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Each
slice: {0}x{1}"&lt;/span&gt;, sliceWidth, sliceHeight);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 52: &lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; tile = 0;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 53: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var
row &lt;span class="kwrd"&gt;in&lt;/span&gt; gridSize.Times()) {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 54: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var column &lt;span class="kwrd"&gt;in&lt;/span&gt; gridSize.Times())
{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 55: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Creating
{0} of {1} ({2},{3})"&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 56: &lt;/span&gt; ++tile, gridSize * gridSize, column, row);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 57: &lt;/span&gt; &lt;span class="kwrd"&gt;using&lt;/span&gt; (var
destBitmap = &lt;span class="kwrd"&gt;new&lt;/span&gt; Bitmap(sliceWidth, sliceHeight)) {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 58: &lt;/span&gt; var sourceData = sourceBitmap.LockBits(&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 59: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Rectangle(column
* sliceWidth,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 60: &lt;/span&gt; row * sliceHeight, sliceWidth,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 61: &lt;/span&gt; sliceHeight),&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 62: &lt;/span&gt; ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 63: &lt;/span&gt; var destData = destBitmap.LockBits(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 64: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Rectangle(0, 0,
sliceWidth, sliceHeight),&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 65: &lt;/span&gt; ImageLockMode.WriteOnly, sourceData.PixelFormat);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 66: &lt;/span&gt; &lt;span class="kwrd"&gt;unsafe&lt;/span&gt; {&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 67: &lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;* pSrc
= (&lt;span class="kwrd"&gt;byte&lt;/span&gt;*)sourceData.Scan0.ToPointer();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 68: &lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;* pDest = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;*)destData.Scan0.ToPointer();&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 69: &lt;/span&gt; &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var
line &lt;span class="kwrd"&gt;in&lt;/span&gt; sliceHeight.Times()) {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 70: &lt;/span&gt; memcpy(pDest, pSrc, sliceWidth * 3);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 71: &lt;/span&gt; pSrc += sourceData.Stride;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 72: &lt;/span&gt; pDest += destData.Stride;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 73: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 74: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 75: &lt;/span&gt; sourceBitmap.UnlockBits(sourceData);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 76: &lt;/span&gt; destBitmap.UnlockBits(destData);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 77: &lt;/span&gt; destBitmap.Save(String.Format(&lt;span class="str"&gt;"{0}_{1}_{2}.png"&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 78: &lt;/span&gt; Path.GetFileNameWithoutExtension(sourcePath),&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 79: &lt;/span&gt; column, row), ImageFormat.Png);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 80: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 81: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 82: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 83: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 84: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 85: &lt;/span&gt; &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception
ex) {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 86: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Error processing
image."&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 87: &lt;/span&gt; Console.WriteLine(ex.ToString());&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 88: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 89: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 90: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 91: &lt;/span&gt; &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ShowUsage()
{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 92: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Usage:"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 93: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"ImageSlicer.exe
sourceImage [gridSize]"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 94: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 95: &lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt; 96: &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=f5216e74-ce9f-4b7a-b1de-157ea51bf987" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,f5216e74-ce9f-4b7a-b1de-157ea51bf987.aspx</comments>
      <category>Fun;Software Development</category>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=95211f13-9e8b-4d4c-b013-b67ccd20a041</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,95211f13-9e8b-4d4c-b013-b67ccd20a041.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,95211f13-9e8b-4d4c-b013-b67ccd20a041.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=95211f13-9e8b-4d4c-b013-b67ccd20a041</wfw:commentRss>
      <title>My team is hiring. Come work on the CLR team!</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,95211f13-9e8b-4d4c-b013-b67ccd20a041.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,95211f13-9e8b-4d4c-b013-b67ccd20a041.aspx</link>
      <pubDate>Fri, 09 May 2008 18:40:09 GMT</pubDate>
      <description>&lt;p&gt;
Why not come work on the Common Language Runtime team at Microsoft?&amp;nbsp; My team
is a team of SDETs (Software Development Engineer in Test) that works in the really
low levels of the CLR.&amp;nbsp; We cover areas like assembly loading/fusion, AppDomains,
the shim (mscoree), and interop.
&lt;/p&gt;
&lt;p&gt;
As an SDET, you are in charge of all aspects of quality for the areas you own. This
means you get to be involved in the design process and be literally the first person
developing code using new features coming out of the team.&amp;nbsp; I've found my last
year and a half here to be extremely satisfying.
&lt;/p&gt;
&lt;p&gt;
This is a pretty exciting time to join the team as we're working on some long-lead
items for the next version of the CLR and we're also busy shipping Silverlight 2 and
.NET Framework 3.5 SP1.
&lt;/p&gt;
&lt;p&gt;
You'll need strong coding, problem-solving, and communication skills.&amp;nbsp; Some background
on the CLR and managed code is a plus, but not required.&amp;nbsp; If you think you've
got what it takes to join the team, &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=95211f13-9e8b-4d4c-b013-b67ccd20a041&amp;amp;url=http%3a%2f%2fmembers.microsoft.com%2fcareers%2fsearch%2fdetails.aspx%3fJobID%3d040443C0-A7C4-407B-A0E4-7D6B5E98BCF4"" target="_blank"&gt;check
out the job details and submit your resume&lt;/a&gt;.&amp;nbsp; I'm happy to answer questions
about the team and the jobs within reason, so feel free to ping me at marklio at [you-know-where].com.
&lt;/p&gt;
&lt;p&gt;
There are several openings in other areas of the team as well.&amp;nbsp; Feel free to
search the other CLR jobs and find the one that's right for you.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=95211f13-9e8b-4d4c-b013-b67ccd20a041" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,95211f13-9e8b-4d4c-b013-b67ccd20a041.aspx</comments>
      <category>Announcements;CLR;News</category>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=498e2e35-1590-4852-92e1-2212157c68f1</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,498e2e35-1590-4852-92e1-2212157c68f1.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,498e2e35-1590-4852-92e1-2212157c68f1.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=498e2e35-1590-4852-92e1-2212157c68f1</wfw:commentRss>
      <title>Silverlight limitations and Constrained Callvirt in IL</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,498e2e35-1590-4852-92e1-2212157c68f1.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,498e2e35-1590-4852-92e1-2212157c68f1.aspx</link>
      <pubDate>Wed, 23 Apr 2008 20:43:46 GMT</pubDate>
      <description>&lt;p&gt;
I've been doing some app-building with Silverlight lately and exploring the limitations
of the platform in comparison to the full desktop CLR and what that means for the
Silverlight "ecosystem".&amp;nbsp; Those limitations can be summed up with 3 items:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Strict sandbox security model&lt;/li&gt;
&lt;li&gt;
Reduced managed framework surface area&lt;/li&gt;
&lt;li&gt;
No binary compatibility with libraries targeting the desktop CLR (eliminates the number
of 3rd party components you can leverage).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
I think #3 will begin to become a non-issue as more component providers provide builds
for Silverlight. #2 can be broken down into 2 areas:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Full technology areas that are unavailable on Silverlight (LinqToSql, WinForms, etc)&lt;/li&gt;
&lt;li&gt;
Reduced/pruned APIs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The second is where my interest lies, and intersects with #1 (the new security model).&amp;nbsp;
We've done extensive threat modeling against our APIs as well as automated tooling
that has either removed (or made internal) certain APIs, or marked them as SecurityCritical,
meaning they cannot be called directly from "user" code.
&lt;/p&gt;
&lt;p&gt;
In addition, the security model requires safe, verifiable user code.&amp;nbsp; Normally
when developing on the desktop CLR, unless you are specifically targeting a low trust
environment, you can do whatever you like.
&lt;/p&gt;
&lt;p&gt;
So, for this exercise, I pulled out my trusty STDF parser (blogged &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=498e2e35-1590-4852-92e1-2212157c68f1&amp;amp;url=http%3a%2f%2fwww.marklio.com%2fmarklio%2fPermaLink%2cguid%2ce3601f31-231b-4a82-b5a7-1c31600ce25c.aspx"" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=498e2e35-1590-4852-92e1-2212157c68f1&amp;amp;url=http%3a%2f%2fwww.marklio.com%2fmarklio%2fPermaLink%2cguid%2c3a89ecce-89a8-470e-a894-bc5cc86ce41d.aspx"" target="_blank"&gt;here&lt;/a&gt;).&amp;nbsp;
I've used this project as a test vehicle for both v2.0 and Orcas, and it's served
well as a project that leverages a large cross-section of features in the Framework,
from high-level stuff like Linq down to expression tree inspection and further down
to LCG/RefEmit.
&lt;/p&gt;
&lt;p&gt;
In short, I was able to get the parser working without too much trouble. I felt like
creating a source bed that intended to target both Silverlight and the Desktop should
be an attainable goal.&amp;nbsp; You just have to switch your mindset from binary compatibility
to source compatibility.
&lt;/p&gt;
&lt;p&gt;
I combated the reduced surface area with extension methods, which worked quite well
to centralize the "overload shims" that needed to be "Silverlight-only", as well as
for a general refactoring tool.&amp;nbsp; My goal is to have all the desktop vs. Silverlight
differences centralized into files that are either included or excluded from the build
depending on which platform I'm targeting.&amp;nbsp; I wish you could create extension
properties.&amp;nbsp; That would let me close all the surface area discrepancies that
aren't caused by missing/irrelevant technology areas.
&lt;/p&gt;
&lt;p&gt;
I was pleased that 99% of my LCG codegen stuff "just worked".&amp;nbsp; I make heavy use
of Reflection.Emit via DynamicMethod to generate my record parsers based on attributes
on the record classes.&amp;nbsp; The 2 problems I ran into were:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Visibility restrictions - The new security model won't let my dynamic methods see
internals.&amp;nbsp; I had used this ability to keep the API clean.&amp;nbsp; I'm still figuring
out the best approach, but it was simple enough just to expose those methods.&lt;/li&gt;
&lt;li&gt;
Verifiability - I had a few places where I was generating unverifiable code.&amp;nbsp;
Some of these were my own codegen bugs, but others were just bad assumptions on my
part.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This brings me to &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=498e2e35-1590-4852-92e1-2212157c68f1&amp;amp;url=http%3a%2f%2fmsdn2.microsoft.com%2fen-us%2flibrary%2fsystem.reflection.emit.opcodes.constrained.aspx"" target="_blank"&gt;constrained
callvirt&lt;/a&gt;, an interesting little IL tidbit I discovered in the porting process.&amp;nbsp;
Calling conventions are subtly different between reference types and value types,
and it also depends on whether the given method is actually overridden in the value
type (which can lead to confusing breaks when that state changes).&amp;nbsp; In the v1.x
days, you always knew the type you were dealing with, so it didn't matter that much
and you could generally always create the right sequence of IL to make a call.&amp;nbsp;
V2.0 introduced generics, which meant that you couldn't emit unified IL for both the
possibility of reference types or value types.&amp;nbsp; This meant there needed to be
a way to unify the IL for the 2 cases.&amp;nbsp; This is where the constrained prefix
came in.&amp;nbsp; It allows you to write unified IL that works regardless of whether
you're working with a value type or a reference type (think generics constrained by
an interface, or calling a method defined on System.Object like ToString()).
&lt;/p&gt;
&lt;p&gt;
Anyway, I was able to fix my unverifiable code by utilizing the constrained prefix.&amp;nbsp;
It also simplified my codegen logic significantly in a number of places where I had
different paths based on whether I was working with a value type or not.
&lt;/p&gt;
&lt;p&gt;
All in all, I was pleased with the results.&amp;nbsp; I'll be posting a sample Silverlight
app using the library when I get some UI stuff figured out.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=498e2e35-1590-4852-92e1-2212157c68f1" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,498e2e35-1590-4852-92e1-2212157c68f1.aspx</comments>
      <category>CLR;Fun;Software Development;Technical</category>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <title>Happy Birthday Peter</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca.aspx</link>
      <pubDate>Mon, 21 Apr 2008 23:28:22 GMT</pubDate>
      <description>&lt;p&gt;
I've been horrible with blogging lately.&amp;nbsp; But, I would be remiss if I&amp;nbsp; neglected
to mention &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca&amp;amp;url=http%3a%2f%2fwww.flatlandmedia.com%2fflatlander%2f"" target="_blank"&gt;Peter&lt;/a&gt;'s
birthday today.&amp;nbsp; Happy Birthday, Peter.
&lt;/p&gt;
&lt;p&gt;
Hopefully the thing that's been clogging my blogging pipes will be gone soon.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,7a2ed9fc-a39c-4ec1-99c0-7bfcf83616ca.aspx</comments>
      <category>Announcements;Fun</category>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=9491e8e3-6bbc-4c3e-a106-7944495db527</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,9491e8e3-6bbc-4c3e-a106-7944495db527.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,9491e8e3-6bbc-4c3e-a106-7944495db527.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=9491e8e3-6bbc-4c3e-a106-7944495db527</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Some of my posts are really reactions to search queries that have previously landed
on my blog.  If they did a search that got to my blog, but I know they didn't
find what they were looking for, chances are they (or someone else) will do the same
again.  And, if I <strong><em>HAVE</em></strong> the information they are looking
for, it makes sense to just add the information, even if it's what I would consider
well-known or common sense information. (common sense for software developers, that
is)
</p>
        <p>
One general search query I see again and again is something like "What is Action&lt;T&gt;
for?" or "What is Func&lt;T&gt;?"
</p>
        <p>
These are framework-provided, generic delegate types.  If you'll recall, delegates
can be thought of as type-safe function pointers.  A delegate type really just
captures a signature as "callable" object.  Leveraging generics to define delegate
types that can capture common signatures is goodness, since they are very flexible
and can be used by anyone.  This also aids in interop between different components,
since a general signature is far more interopable than custom delegate types.
</p>
        <p>
In v2.0, several functional-looking APIs were added that took delegates as arguments
(think List&lt;T&gt;), so instead of adding a special delegate type for each API,
several "generic" delegates were added to capture the "essence" of a signature such
as Action&lt;T&gt; which takes T and does some action (returning void), Predicate&lt;T&gt;
which takes T and returns bool (presumably doing some test against T), Comparer&lt;T&gt;
which compares 2 T's, etc.
</p>
        <p>
In v3.5, even more generalized functional patterns were introduced (used heavily in
Linq).  And we added a bunch more Action&lt;&gt; "overloads" for functions returning
void, and added Func&lt;&gt; "overloads" for functions with a return value. 
(I use overload loosely since these are classes and not methods) These patterns dropped
the semantic "meaning" of the delegate, and just went straight to the idea of capturing
a signature.
</p>
        <p>
These framework-provided delegates are useful for using in your own code rather than
creating your own.  Whether you leverage the Linq-centric, super-generic Action/Func
pattern, or opt to consume the more meaningful v2.0 Predicate, Comparer, etc. is up
to you.
</p>
        <img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=9491e8e3-6bbc-4c3e-a106-7944495db527" />
      </body>
      <title>What are the generic Delegates in the framework for?</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,9491e8e3-6bbc-4c3e-a106-7944495db527.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,9491e8e3-6bbc-4c3e-a106-7944495db527.aspx</link>
      <pubDate>Mon, 25 Feb 2008 19:12:15 GMT</pubDate>
      <description>&lt;p&gt;
Some of my posts are really reactions to search queries that have previously landed
on my blog.&amp;nbsp; If they did a search that got to my blog, but I know they didn't
find what they were looking for, chances are they (or someone else) will do the same
again.&amp;nbsp; And, if I &lt;strong&gt;&lt;em&gt;HAVE&lt;/em&gt;&lt;/strong&gt; the information they are looking
for, it makes sense to just add the information, even if it's what I would consider
well-known or common sense information. (common sense for software developers, that
is)
&lt;/p&gt;
&lt;p&gt;
One general search query I see again and again is something like "What is Action&amp;lt;T&amp;gt;
for?" or "What is Func&amp;lt;T&amp;gt;?"
&lt;/p&gt;
&lt;p&gt;
These are framework-provided, generic delegate types.&amp;nbsp; If you'll recall, delegates
can be thought of as type-safe function pointers.&amp;nbsp; A delegate type really just
captures a signature as "callable" object.&amp;nbsp; Leveraging generics to define delegate
types that can capture common signatures is goodness, since they are very flexible
and can be used by anyone.&amp;nbsp; This also aids in interop between different components,
since a general signature is far more interopable than custom delegate types.
&lt;/p&gt;
&lt;p&gt;
In v2.0, several functional-looking APIs were added that took delegates as arguments
(think List&amp;lt;T&amp;gt;), so instead of adding a special delegate type for each API,
several "generic" delegates were added to capture the "essence" of a signature such
as Action&amp;lt;T&amp;gt; which takes T and does some action (returning void), Predicate&amp;lt;T&amp;gt;
which takes T and returns bool (presumably doing some test against T), Comparer&amp;lt;T&amp;gt;
which compares 2 T's, etc.
&lt;/p&gt;
&lt;p&gt;
In v3.5, even more generalized functional patterns were introduced (used heavily in
Linq).&amp;nbsp; And we added a bunch more Action&amp;lt;&amp;gt; "overloads" for functions returning
void, and added Func&amp;lt;&amp;gt; "overloads" for functions with a return value.&amp;nbsp;
(I use overload loosely since these are classes and not methods) These patterns dropped
the semantic "meaning" of the delegate, and just went straight to the idea of capturing
a signature.
&lt;/p&gt;
&lt;p&gt;
These framework-provided delegates are useful for using in your own code rather than
creating your own.&amp;nbsp; Whether you leverage the Linq-centric, super-generic Action/Func
pattern, or opt to consume the more meaningful v2.0 Predicate, Comparer, etc. is up
to you.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=9491e8e3-6bbc-4c3e-a106-7944495db527" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,9491e8e3-6bbc-4c3e-a106-7944495db527.aspx</comments>
      <category>CLR;Delegates;Fun;Software Development</category>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=eb80742a-9b93-42c6-8372-d8191edb0d84</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,eb80742a-9b93-42c6-8372-d8191edb0d84.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,eb80742a-9b93-42c6-8372-d8191edb0d84.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=eb80742a-9b93-42c6-8372-d8191edb0d84</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <title>The eagle has landed</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,eb80742a-9b93-42c6-8372-d8191edb0d84.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,eb80742a-9b93-42c6-8372-d8191edb0d84.aspx</link>
      <pubDate>Sun, 24 Feb 2008 22:01:53 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.marklio.com/marklio/ct.ashx?id=eb80742a-9b93-42c6-8372-d8191edb0d84&amp;amp;url=http%3a%2f%2fwww.flickr.com%2fphotos%2fmarklio%2f2288625437%2f"" target="_blank"&gt;&lt;img style="margin: 0px 5px 5px 0px" src="http://farm4.static.flickr.com/3168/2288625437_f12180d60b_m.jpg" align="left" border="0"&gt;&lt;/a&gt; We
were hanging out after church today, and I saw a large flash of black and white zoom
by the sliding glass door that looks out over the deck into the backyard.&amp;nbsp; I
immediately jumped up and grabbed for the camera and in my panicked state, took several
of the worst pictures ever of a majestic bald eagle as it sat in a tree less than
20 feet away from the house.
&lt;/p&gt;
&lt;p&gt;
It was obscured by several other trees, so the focus isn't great.&amp;nbsp; And my shutter
speed was too slow to eliminate the excited shake in my hands.&amp;nbsp; I tried to step
out onto the deck to get a better shot, but it flew away.&amp;nbsp; It was enormous.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=eb80742a-9b93-42c6-8372-d8191edb0d84" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,eb80742a-9b93-42c6-8372-d8191edb0d84.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9</wfw:commentRss>
      <title>What is System.__Canon and why is it on my stack?</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9.aspx</link>
      <pubDate>Tue, 12 Feb 2008 19:56:35 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;This is one of those entries that attempts to fill a void in online search for
a particular topic.&amp;nbsp; I ramble on for a while to give enough context so that a
search engine can match it up in a relevant manner.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
I was debugging something the other day, and thought I had come across a heinous bug
in the CLR.&amp;nbsp; Turns out, everything was working fine and the bug was in the app.
&lt;/p&gt;
&lt;p&gt;
A program was crashing and it was a managed exception, so I attached to it with VS2008
and dug in.&amp;nbsp; The first thing I noted was that this was a retail build, so &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9&amp;amp;url=http%3a%2f%2fwww.hanselman.com%2fblog%2fReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx"" target="_blank"&gt;my
stack was collapsed in a number of places&lt;/a&gt;... expected, keep moving.&amp;nbsp; Then,
I noted an interesting frame on my stack (this is a contrived example, not the actual
thing I saw):
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CanonTest.exe!CanonTest.GenericType&amp;lt;&lt;font color="#ff0000"&gt;&lt;strong&gt;System.__Canon&lt;/strong&gt;&lt;/font&gt;,int&amp;gt;.SomeOperation()
+ 0x55 bytes&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
That's weird, what is System.__Canon and what's it doing here? Surely this must be
a horrible CLR bug where my method tables are being corrupted!&amp;nbsp; Internet searches
seem to be confirming my thoughts.&amp;nbsp; A few others with random __Canon's showing
up on the stack do look like bugs.&amp;nbsp; After a bit more reasoning, I come to the
conclusion that System.__Canon must be special in some way since it follows the pattern
for such things...&amp;nbsp; marked internal, pre-pended with double-underscore.
&lt;/p&gt;
&lt;p&gt;
A few emails later, I had my answer.&amp;nbsp; System.__Canon is the special type that
is used to identify "canonical" generic type instantiations. It typically only shows
up in release builds, so you don't normally see it on the stack while debugging.&amp;nbsp;
So, it's easy to assume something's wrong when you do see it.
&lt;/p&gt;
&lt;p&gt;
If you'll recall, one of the really cool things about the Generics implementation
is that it allows for code sharing.&amp;nbsp; Jitted methods can be shared between compatible
type instantiations.&amp;nbsp; For instance, the code for SomeGenericType&amp;lt;string&amp;gt;
can likely be shared with SomeGenericType&amp;lt;Foo&amp;gt; (where Foo is another reference
type. We don't currently share code between value types, so you'll continue to see
those on the stack such as in the example).&amp;nbsp; That shared code needs to live somewhere,
so we have the concept of a "canonical" generic type instantiation that is identified
by __Canon as the type parameter.
&lt;/p&gt;
&lt;p&gt;
Also, in alot of debugger stack representations you'll get the GenericType`2 form
rather than expanded form.&amp;nbsp; In that case, you never see __Canon.
&lt;/p&gt;
&lt;p&gt;
For some more info on Generics and code sharing, see &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9&amp;amp;url=http%3a%2f%2fblogs.msdn.com%2fjoelpob%2farchive%2f2004%2f11%2f17%2f259224.aspx"" target="_blank"&gt;Joel
Pobar's excellent blog entry on the subject&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9.aspx</comments>
      <category>CLR;Software Development;Technical</category>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=0ec107a6-82af-4530-b373-38bb30930548</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,0ec107a6-82af-4530-b373-38bb30930548.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,0ec107a6-82af-4530-b373-38bb30930548.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=0ec107a6-82af-4530-b373-38bb30930548</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>You say the darnedest things to kids</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,0ec107a6-82af-4530-b373-38bb30930548.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,0ec107a6-82af-4530-b373-38bb30930548.aspx</link>
      <pubDate>Wed, 09 Jan 2008 18:40:08 GMT</pubDate>
      <description>&lt;p&gt;
A twist on &lt;a href="http://www.marklio.com/marklio/ct.ashx?id=0ec107a6-82af-4530-b373-38bb30930548&amp;amp;url=http%3a%2f%2fen.wikipedia.org%2fwiki%2fKids_Say_the_Darnedest_Things"" target="_blank"&gt;Bill
Cosby's humerous show&lt;/a&gt;,&amp;nbsp; the other day I said the following to my daughter:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
I'm sorry, donkeys don't stick to the refrigerator.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Taken out of context, Becky thought it was pretty funny. Here's the context: I was
playing with Jenna in the kitchen the other day, and she was playing with 2 plastic
donkeys as well as some refrigerator magnets.&amp;nbsp; After seeing how the magnets stuck
to the refrigerator, she tried to do the same with the plastic donkeys, which didn't
work of course.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=0ec107a6-82af-4530-b373-38bb30930548" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,0ec107a6-82af-4530-b373-38bb30930548.aspx</comments>
      <category>Fun;Jenna</category>
    </item>
    <item>
      <trackback:ping>http://www.marklio.com/marklio/Trackback.aspx?guid=df8d6471-83fd-4f66-a799-ef8274979f0e</trackback:ping>
      <pingback:server>http://www.marklio.com/marklio/pingback.aspx</pingback:server>
      <pingback:target>http://www.marklio.com/marklio/PermaLink,guid,df8d6471-83fd-4f66-a799-ef8274979f0e.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.marklio.com/marklio/CommentView,guid,df8d6471-83fd-4f66-a799-ef8274979f0e.aspx</wfw:comment>
      <wfw:commentRss>http://www.marklio.com/marklio/SyndicationService.asmx/GetEntryCommentsRss?guid=df8d6471-83fd-4f66-a799-ef8274979f0e</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The CTP for the MVC framework includes support for master-page, page, and user-control
based views.  I thought it might be interesting to enable .ashx-based views for
things like RSS generation via System.Xml.Linq, or other more "raw" view output.
</p>
        <p>
As it turns out, this is fairly trivial.  The place we need to extend is the
IViewFactory returned by Controller.ViewFactory.  This is the component that
is responsible for creating the view when a call to RenderView is made.
</p>
        <p>
The default view factory is the WebFormViewFactory, which knows how to generate views
based on .master, .aspx, and .ascx views.  Since we want to add support for .ashx,
we'll use WebFormViewFactory as a starting place.  We'll inherit from WebFormViewFactory
and override CreateView to supply our extra .ashx lookup.
</p>
        <pre>
          <span style="color: #0000ff">using</span> System; <span style="color: #0000ff">using</span> System.Globalization; <span style="color: #0000ff">using</span> System.IO; <span style="color: #0000ff">using</span> System.Web; <span style="color: #0000ff">using</span> System.Web.Compilation; <span style="color: #0000ff">using</span> System.Web.Mvc; <span style="color: #0000ff">public</span><span style="color: #0000ff">class</span> SpecialViewFactory
: WebFormViewFactory { <span style="color: #0000ff">static</span><span style="color: #0000ff">readonly</span><span style="color: #0000ff">string</span>[]
ViewLocationFormats = <span style="color: #0000ff">new</span><span style="color: #0000ff">string</span>[]
{ "<span style="color: #8b0000">~/Views/{1}/{0}.ashx</span>", "<span style="color: #8b0000">~/Views/Shared/{0}.ashx</span>"
}; ControllerContext _ControllerContext; #region IViewFactory Members <span style="color: #0000ff">protected</span><span style="color: #0000ff">override</span> IView
CreateView(ControllerContext controllerContext, <span style="color: #0000ff">string</span> viewName, <span style="color: #0000ff">string</span> masterName, <span style="color: #0000ff">object</span> viewData)
{ _ControllerContext = controllerContext; <span style="color: #008000">//check to
see if there is an ashx that matches here.</span><span style="color: #0000ff">object</span><span style="color: #0000ff">value</span> = <span style="color: #0000ff">null</span>;
controllerContext.RouteData.Values.TryGetValue("<span style="color: #8b0000">controller</span>", <span style="color: #0000ff">out</span><span style="color: #0000ff">value</span>); <span style="color: #0000ff">string</span> controllerName
= <span style="color: #0000ff">value</span><span style="color: #0000ff">as</span><span style="color: #0000ff">string</span>; <span style="color: #0000ff">if</span> (controllerName
== <span style="color: #0000ff">null</span>) { <span style="color: #0000ff">throw</span><span style="color: #0000ff">new</span> InvalidOperationException("<span style="color: #8b0000">No
route data value available for controller.</span>"); } Type viewType = <span style="color: #0000ff">null</span>; <span style="color: #0000ff">foreach</span> (var
loc <span style="color: #0000ff">in</span> ViewLocationFormats) { var path = <span style="color: #0000ff">string</span>.Format(CultureInfo.InvariantCulture,
loc, viewName, controllerName); viewType = GetCompiledType(path); <span style="color: #0000ff">if</span> (viewType
!= <span style="color: #0000ff">null</span>) <span style="color: #0000ff">break</span>;
} <span style="color: #0000ff">if</span> (viewType == <span style="color: #0000ff">null</span>)
{ <span style="color: #0000ff">return</span><span style="color: #0000ff">base</span>.CreateView(controllerContext,
viewName, masterName, viewData); } <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">typeof</span>(IView).IsAssignableFrom(viewType))
{ <span style="color: #008000">//TODO: better exception</span><span style="color: #0000ff">throw</span><span style="color: #0000ff">new</span> InvalidOperationException("<span style="color: #8b0000">Type
not a view</span>"); } var view = (IView)Activator.CreateInstance(viewType); var viewHandler
= view <span style="color: #0000ff">as</span> ViewHandler; <span style="color: #0000ff">if</span> (viewHandler
!= <span style="color: #0000ff">null</span>) viewHandler.ViewData = viewData; _ControllerContext
= <span style="color: #0000ff">null</span>; <span style="color: #0000ff">return</span> view;
} <span style="color: #0000ff">private</span> Type GetCompiledType(<span style="color: #0000ff">string</span> path)
{ Type compiledType = <span style="color: #0000ff">null</span>; <span style="color: #0000ff">try</span> { <span style="color: #0000ff">if</span> (File.Exists(_ControllerContext.HttpContext.Request.MapPath(path)))
{ compiledType = BuildManager.GetCompiledType(path); } } <span style="color: #0000ff">catch</span> (HttpCompileException)
{ <span style="color: #0000ff">throw</span>; } <span style="color: #0000ff">catch</span> (HttpParseException)
{ <span style="color: #0000ff">throw</span>; } <span style="color: #0000ff">catch</span> (HttpException)
{ } <span style="color: #0000ff">return</span> compiledType; } #endregion } </pre>
        <p>
GetCompiledType had to be replicated as it isn't exposed in the base class. 
Note, I added a File.Exists check before I attempt to get the compiled type from the
BuildManager. This was really to avoid having to deal with a bunch of first chance
exceptions in the debug, although it seems likely that avoiding the exception is a
good thing.  It wouldn't catch handlers that are mapped in the app dynamically
or via web.config.
</p>
        <p>
As you can see, I also added a ViewHandler class that my handlers can inherit from
that gives them the same goodies that the other views get, but I'll leave that as
an exercise for the reader to implement.
</p>
        <p>
So, now the only thing remaining is to inject our special view factory into the pipeline
instead of the default.  A simple way to do this is to set the ViewFactory property
in the constructor of any controller that needs .ashx support. Now, you can create
.ashx files and use them as views!
</p>
        <p>
Next time, I'll show you how to add support for routing controller actions based on
data not in the URL.
</p>
        <img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=df8d6471-83fd-4f66-a799-ef8274979f0e" />
      </body>
      <title>Adding support for .ashx-based views in ASP.net MVC</title>
      <guid isPermaLink="false">http://www.marklio.com/marklio/PermaLink,guid,df8d6471-83fd-4f66-a799-ef8274979f0e.aspx</guid>
      <link>http://www.marklio.com/marklio/PermaLink,guid,df8d6471-83fd-4f66-a799-ef8274979f0e.aspx</link>
      <pubDate>Thu, 03 Jan 2008 23:46:58 GMT</pubDate>
      <description>&lt;p&gt;
The CTP for the MVC framework includes support for master-page, page, and user-control
based views.&amp;nbsp; I thought it might be interesting to enable .ashx-based views for
things like RSS generation via System.Xml.Linq, or other more "raw" view output.
&lt;/p&gt;
&lt;p&gt;
As it turns out, this is fairly trivial.&amp;nbsp; The place we need to extend is the
IViewFactory returned by Controller.ViewFactory.&amp;nbsp; This is the component that
is responsible for creating the view when a call to RenderView is made.
&lt;/p&gt;
&lt;p&gt;
The default view factory is the WebFormViewFactory, which knows how to generate views
based on .master, .aspx, and .ascx views.&amp;nbsp; Since we want to add support for .ashx,
we'll use WebFormViewFactory as a starting place.&amp;nbsp; We'll inherit from WebFormViewFactory
and override CreateView to supply our extra .ashx lookup.
&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Globalization; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.IO; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web.Compilation; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Web.Mvc; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SpecialViewFactory
: WebFormViewFactory { &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
ViewLocationFormats = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
{ "&lt;span style="color: #8b0000"&gt;~/Views/{1}/{0}.ashx&lt;/span&gt;", "&lt;span style="color: #8b0000"&gt;~/Views/Shared/{0}.ashx&lt;/span&gt;"
}; ControllerContext _ControllerContext; #region IViewFactory Members &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; IView
CreateView(ControllerContext controllerContext, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; viewName, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; masterName, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; viewData)
{ _ControllerContext = controllerContext; &lt;span style="color: #008000"&gt;//check to
see if there is an ashx that matches here.&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
controllerContext.RouteData.Values.TryGetValue("&lt;span style="color: #8b0000"&gt;controller&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;out&lt;/span&gt; &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;); &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; controllerName
= &lt;span style="color: #0000ff"&gt;value&lt;/span&gt; &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (controllerName
== &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) { &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InvalidOperationException("&lt;span style="color: #8b0000"&gt;No
route data value available for controller.&lt;/span&gt;"); } Type viewType = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var
loc &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; ViewLocationFormats) { var path = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(CultureInfo.InvariantCulture,
loc, viewName, controllerName); viewType = GetCompiledType(path); &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (viewType
!= &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;
} &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (viewType == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
{ &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.CreateView(controllerContext,
viewName, masterName, viewData); } &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IView).IsAssignableFrom(viewType))
{ &lt;span style="color: #008000"&gt;//TODO: better exception&lt;/span&gt; &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InvalidOperationException("&lt;span style="color: #8b0000"&gt;Type
not a view&lt;/span&gt;"); } var view = (IView)Activator.CreateInstance(viewType); var viewHandler
= view &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; ViewHandler; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (viewHandler
!= &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) viewHandler.ViewData = viewData; _ControllerContext
= &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; view;
} &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Type GetCompiledType(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; path)
{ Type compiledType = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;try&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (File.Exists(_ControllerContext.HttpContext.Request.MapPath(path)))
{ compiledType = BuildManager.GetCompiledType(path); } } &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (HttpCompileException)
{ &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;; } &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (HttpParseException)
{ &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;; } &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (HttpException)
{ } &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; compiledType; } #endregion } &lt;/pre&gt;
&lt;p&gt;
GetCompiledType had to be replicated as it isn't exposed in the base class.&amp;nbsp;
Note, I added a File.Exists check before I attempt to get the compiled type from the
BuildManager. This was really to avoid having to deal with a bunch of first chance
exceptions in the debug, although it seems likely that avoiding the exception is a
good thing.&amp;nbsp; It wouldn't catch handlers that are mapped in the app dynamically
or via web.config.
&lt;/p&gt;
&lt;p&gt;
As you can see, I also added a ViewHandler class that my handlers can inherit from
that gives them the same goodies that the other views get, but I'll leave that as
an exercise for the reader to implement.
&lt;/p&gt;
&lt;p&gt;
So, now the only thing remaining is to inject our special view factory into the pipeline
instead of the default.&amp;nbsp; A simple way to do this is to set the ViewFactory property
in the constructor of any controller that needs .ashx support. Now, you can create
.ashx files and use them as views!
&lt;/p&gt;
&lt;p&gt;
Next time, I'll show you how to add support for routing controller actions based on
data not in the URL.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.marklio.com/marklio/aggbug.ashx?id=df8d6471-83fd-4f66-a799-ef8274979f0e" /&gt;</description>
      <comments>http://www.marklio.com/marklio/CommentView,guid,df8d6471-83fd-4f66-a799-ef8274979f0e.aspx</comments>
      <category>Software Development;Technical</category>
    </item>
  </channel>
</rss>