<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;C08GQHk7fyp7ImA9WhRaFk4.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828</id><updated>2012-02-19T01:10:21.707-05:00</updated><category term="Reporting" /><category term="C#" /><category term="node.js" /><category term="Mongo" /><category term="WebForms" /><category term="javascript" /><category term="ReportViwer" /><category term="AWSSDK" /><category term="Linq" /><category term="Ninject" /><category term="Amazon" /><title>invalidoperation</title><subtitle type="html">how do i wrote codes</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/invalidoperationdotcom" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="invalidoperationdotcom" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;C08GQHk6eyp7ImA9WhRaFk4.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-5852141617833375289</id><published>2012-02-19T01:04:00.001-05:00</published><updated>2012-02-19T01:10:21.713-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-19T01:10:21.713-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AWSSDK" /><category scheme="http://www.blogger.com/atom/ns#" term="Ninject" /><category scheme="http://www.blogger.com/atom/ns#" term="Amazon" /><title>Dynamically Binding AWSSDK Classes with Ninject</title><content type="html">&lt;p&gt;Lately I’ve been toying around with Amazon’s cloud platform in .Net using the &lt;a href="http://nuget.org/packages/AWSSDK"&gt;Amazon Web Services SDK&lt;/a&gt; (AWSSDK). Also along for the ride has been Ninject, which is a pretty awesome dependency injection framework. So if I want to have a class have a constructor dependency from an AWSSDK client class, that has to be wired up the same way your regular non-Amazon classes are, in a NinjectModule. &lt;/p&gt;  &lt;p&gt;Fortunately, there are interfaces for all the client classes in AWSSDK, albeit with an unusual naming structure. The class for calling the Simple Notification Service is called &lt;strong&gt;AmazonSimpleNotificationServiceClient&lt;/strong&gt;, but it’s corresponding interface is &lt;strong&gt;AmazonSimpleNotificationService&lt;/strong&gt;. Note the loss of ‘Client’ on the end, and that it doesn’t begin with a capital I which is the typical norm for C# interfaces. Anyways, that won’t prevent you from using them in Ninject. The problem is that there are 20, count ‘em, 20 of these client classes. You &lt;em&gt;could&lt;/em&gt; manually write all 20 in individual calls to Bind&amp;lt;T&amp;gt; but where’s the fun in that? &lt;/p&gt;  &lt;p&gt;This module will load them based on their aforementioned naming convention.&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;	&lt;br /&gt;    public class AwsModule : NinjectModule&lt;br /&gt;    {&lt;br /&gt;        public override void Load()&lt;br /&gt;        {&lt;br /&gt;            var awsAssembly = typeof(AWSClientFactory).Assembly;&lt;br /&gt;&lt;br /&gt;            var amazonClientTypes = from t in awsAssembly.GetExportedTypes()&lt;br /&gt;                                    where t.IsClass &amp;amp;&amp;amp; t.IsAbstract == false &lt;br /&gt;                                    &amp;amp;&amp;amp; t.IsPublic &amp;amp;&amp;amp; t.Name.EndsWith(&amp;quot;Client&amp;quot;)&lt;br /&gt;                                    select t;&lt;br /&gt;&lt;br /&gt;            foreach (var clientType in amazonClientTypes)&lt;br /&gt;            {&lt;br /&gt;                string clientTypeName = clientType.Name;&lt;br /&gt;                int clientIndex = clientTypeName.LastIndexOf(&amp;quot;Client&amp;quot;);&lt;br /&gt;                string expectedInterfaceName = clientTypeName.Remove(clientIndex, 6);&lt;br /&gt;&lt;br /&gt;                Type interfaceType = (from clInterface in clientType.GetInterfaces()&lt;br /&gt;                                  where clInterface.Name == expectedInterfaceName&lt;br /&gt;                                  select clInterface).FirstOrDefault();&lt;br /&gt;&lt;br /&gt;                if (interfaceType != null)&lt;br /&gt;                    Bind(interfaceType).To(clientType);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Note that this results in binds that end up resolving to their default constructors, not any of the overloads that take credentials or config objects. As is, the above code will use credentials from your app.config/web.config file by searching for &lt;strong&gt;AWSAccessKey&lt;/strong&gt; and &lt;strong&gt;AWSSecretKey&lt;/strong&gt; in your &lt;strong&gt;appSettings&lt;/strong&gt; section. Which I’m fine with. I could have this or another module bind &lt;strong&gt;AWSCredentials &lt;/strong&gt;to anything that derives from it, like &lt;strong&gt;BasicAWSCredentials&lt;/strong&gt;. And similarly for &lt;strong&gt;ClientConfig &lt;/strong&gt;if that’s your bag.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-5852141617833375289?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/5852141617833375289/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2012/02/dynamically-binding-awssdk-classes-with.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/5852141617833375289?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/5852141617833375289?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2012/02/dynamically-binding-awssdk-classes-with.html" title="Dynamically Binding AWSSDK Classes with Ninject" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUcHQno-fCp7ImA9WhRWFUs.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-6085307811814114242</id><published>2012-01-02T20:45:00.001-05:00</published><updated>2012-01-02T22:57:13.454-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-02T22:57:13.454-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="Mongo" /><title>Managing Collection Names for your MongoDb Classes</title><content type="html">&lt;p&gt;Recently I took another look at &lt;a href="http://www.mongodb.com/"&gt;MongoDb&lt;/a&gt;, the document database that’s been around for quite a while. Now there’s a (really good) official &lt;a href="http://www.mongodb.org/display/DOCS/CSharp+Language+Center"&gt;C# driver&lt;/a&gt;. Coupled with &lt;a href="http://nuget.org/packages/FluentMongo/1.0.0.0"&gt;third party LINQ support&lt;/a&gt; and some pretty damn &lt;a href="http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial"&gt;good documentation&lt;/a&gt;, and I don’t see much reason to use &lt;a href="https://github.com/atheken/NoRM/"&gt;NoRm&lt;/a&gt; or any other the other homegrown MongoDb .Net drivers.&lt;/p&gt; &lt;p&gt;One thing that stuck out to me was that there’s no implicit convention using the mapping capabilities to set the collection name for a given class type. Which, if you’re using generic repositories and you only have a System.Type, leaves you with the only option of hardcoding them (bad) or basing them off of the type’s Name or FullName (less bad). I wasn’t thrilled with either option so I wrote some extension methods to make them definable in the same manor as your class maps if you’re using BsonClassMap. Check it: &lt;/p&gt;&lt;pre class="c#" name="code"&gt;    public static class BsonClassMapExtensions&lt;br /&gt;    {&lt;br /&gt;        private static ConcurrentDictionary&amp;lt;Type, string&amp;gt; _cache = new ConcurrentDictionary&amp;lt;Type, string&amp;gt;();&lt;br /&gt;&lt;br /&gt;        public static string GetCollectionName(this BsonClassMap classMap)&lt;br /&gt;        {&lt;br /&gt;            string result = null;&lt;br /&gt;&lt;br /&gt;            if (_cache.TryGetValue(classMap.ClassType, out result))&lt;br /&gt;                return result; &lt;br /&gt;            else&lt;br /&gt;                return classMap.ClassType.Name;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public static void SetCollectionName(this BsonClassMap classMap, string collectionName)&lt;br /&gt;        {&lt;br /&gt;            if (string.IsNullOrEmpty(collectionName))&lt;br /&gt;                throw new InvalidOperationException("Collection name must be valid string.");&lt;br /&gt;&lt;br /&gt;            _cache[classMap.ClassType] = collectionName;&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;Now I can specify collection names as so: &lt;pre class="c#" name="code"&gt;            if (BsonClassMap.IsClassMapRegistered(typeof(Blog)) == false)&lt;br /&gt;            {&lt;br /&gt;                BsonClassMap.RegisterClassMap&amp;lt;Blog&amp;gt;(cm =&amp;gt;&lt;br /&gt;                    {&lt;br /&gt;                        cm.AutoMap();&lt;br /&gt;                        cm.MapIdProperty(x =&amp;gt; x.Id);&lt;br /&gt;                        cm.SetCollectionName("Blogs");&lt;br /&gt;                    }&lt;br /&gt;                );&lt;br /&gt;            }&lt;/pre&gt;&lt;br /&gt;And in my Mongo infrastructure/unit of work/repository implementation I can use &lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;BsonClassMap.LookupClassMap(typeof(Blog)).GetCollectionName();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;when necessary and &lt;em&gt;it just works&lt;/em&gt;. Nice. &lt;br /&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-6085307811814114242?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/6085307811814114242/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2012/01/managing-collection-names-for-your.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/6085307811814114242?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/6085307811814114242?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2012/01/managing-collection-names-for-your.html" title="Managing Collection Names for your MongoDb Classes" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEIDRno4fyp7ImA9WhdXGU4.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-6291260412401620014</id><published>2011-09-02T00:08:00.001-04:00</published><updated>2011-09-02T00:09:37.437-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-02T00:09:37.437-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="node.js" /><title>Getting Started With Node.js</title><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Recently I’ve been playing around with Node.js, the new hotness that is event-based server side JavaScript. It’s been a bit challenging figuring out how to get it going on Windows since Windows support has only just recently been added. So here’s what I did to get all set up writing Node.js apps on Windows. This is more of a brain dump than anything because I have a tendency to get enamored with the new shiny thing and then ignore it for months until I come back to it having forgot all the details on the environment I had set up.&lt;/p&gt; &lt;p&gt;1 – Download the latest Node.js Windows executable from the most recent post on the &lt;a href="http://blog.nodejs.org/"&gt;Node.js blog&lt;/a&gt;. I put mine in c:\node&lt;/p&gt; &lt;p&gt;2 – Download and install &lt;a href="http://python.org/"&gt;Python 2.7.2&lt;/a&gt; It has to be 2.x, this is a prerequisite for the next step.&lt;/p&gt; &lt;p&gt;3 – Download ryppi.py from it’s &lt;a href="https://github.com/japj/ryppi"&gt;github repository&lt;/a&gt; and shove it in the same directory where you put node.exe. This is a python script that emulates &lt;strong&gt;npm&lt;/strong&gt;, the node package manager, which does &lt;strong&gt;NOT&lt;/strong&gt; support Windows, even under cygwin.&lt;/p&gt; &lt;p&gt;4 – Use ryppi.py in place of npm. In blog posts, where you see &lt;em&gt;&lt;strong&gt;npm install &amp;lt;packagename&amp;gt;&lt;/strong&gt;&lt;/em&gt;, execute &lt;em&gt;&lt;strong&gt;ryppi.py install &amp;lt;packagename&amp;gt;&lt;/strong&gt;&lt;/em&gt; in a command prompt where your node.exe is.&lt;/p&gt; &lt;p&gt;5 – Save &lt;a href="http://nodejs.org/"&gt;the hello world web server sample&lt;/a&gt; as helloworld.js in your node directory and run &lt;strong&gt;&lt;em&gt;node.exe helloworld.js&lt;/em&gt;&lt;/strong&gt; from a command line.&lt;/p&gt; &lt;p&gt;I should mention that prior to doing all this I tried building node from source and executing it under cygwin which is detailed &lt;a href="https://github.com/joyent/node/wiki/Building-node.js-on-Cygwin-(Windows)"&gt;over on github&lt;/a&gt;. This is painful and error prone and I would recommend avoiding unless you really want to for some reason.&lt;/p&gt; &lt;p&gt;Helpful / Interesting link dump:&lt;/p&gt; &lt;p&gt;- &lt;a href="http://nodester.com/"&gt;Nodester.com&lt;/a&gt; is a node.js cloud hosting. Literally run a few command line utilities and your node app is running on a subdomain on nodester.com. I haven’t tried it out yet but it looks impressive.&lt;/p&gt; &lt;p&gt;- &lt;a href="http://nodecasts.org/"&gt;Nodecasts.org&lt;/a&gt; is a site for screencasts about node. Only two so far though.&lt;/p&gt; &lt;p&gt;- &lt;a href="http://expressjs.com/"&gt;Expressjs.com&lt;/a&gt; seems to be the dominant web framework for node.js. &lt;/p&gt; &lt;p&gt;- &lt;a href="https://github.com/visionmedia/express-resource"&gt;Express-Resource&lt;/a&gt; is a module for express I’ve been playing around with that adds simplified RESTful routing over express.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-6291260412401620014?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/6291260412401620014/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2011/09/getting-started-with-nodejs.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/6291260412401620014?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/6291260412401620014?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2011/09/getting-started-with-nodejs.html" title="Getting Started With Node.js" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEMDQXs9eCp7ImA9WhRWFUg.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-3520209467341163036</id><published>2011-07-04T14:57:00.001-04:00</published><updated>2012-01-02T21:07:50.560-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-02T21:07:50.560-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WebForms" /><category scheme="http://www.blogger.com/atom/ns#" term="Linq" /><title>Linq to Sql and ObjectDataSource: BFF</title><content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is a re-post from my previous blog. I had mentioned this in an old &lt;a href="http://stackoverflow.com/questions/1469531/linq-to-sql-repository-pattern-dynamic-orderby"&gt;StackOverflow question&lt;/a&gt; and decided to re-post it. Yes, I know the width of this blog is not conducive to big chunks of code. I’ll fix it sometime.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Of all the controls in the Asp.Net WebForms family I think I like the ObjectDataSource the most. It's a shiny beacon of hope in a framework otherwise bogged down by the perils of ViewState, heavy and un-testable infrastructure classes, and much to be desired in terms of abstractions. I know everyone else is all about the MVC angle bracket soup these days but for those (stuck or by choice) in WebForms land, ODS is fantastic. What it allows you to do, in short, is to make often awkward data-binding your bitch. Let's see how.&lt;/p&gt; &lt;p&gt;The essence of all data source controls is allowing you, the developer, to short-circuit traditional architectural techniques like layering and get to having working CRUD in a very just-let-me-get-this-done-and-go-home-what-do-you-mean-unit-testing fashion. SqlDataSource goes direct to a database, XmlDataSource goes to xml, and so on. ObjectDataSource is the only one that lets you break out of the 2-tier forms-over-data model that Microsoft likes to push. But what about LinqDataSource? Well, ODS works by binding to methods on a specified class in your code. Which, since it's your code, allows you much more freedom than any other the others, including the LinqDataSource. Want to provide a specific instance of the binding class to be consumed by the ODS at runtime by your DI container of choice? Want to invoke custom business logic or validation during the CRUD binding-calls? Want to use constructor injection and make your binding class actually, you know, testable? Want to actually put code in a place other than a web form's code-behind? Want to leverage server-side paging in Linq to Sql to only fetch and display the data you're concerned with showing? Want to pipe in some custom data from the http cache? All doable with ODS, the others not so much.&lt;/p&gt; &lt;p&gt;For a class to serve as a binding source for an ObjectDataSource, it needs:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;One or more methods to return stuff to bind against. Business objects, a DataTable, whatever. These methods can optionally have  &lt;ul&gt; &lt;li&gt;Two integer parameters for paging (defaulting to 'maximumRows' and 'startRowIndex') indicating a subset of data to be returned  &lt;li&gt;A string parameter for sorting, provided in the form of &lt;strong&gt;ColumnName DIRECTION&lt;/strong&gt; such as &lt;em&gt;ProductName ASC&lt;/em&gt; or &lt;em&gt;UnitPrice DESC&lt;/em&gt; &lt;/li&gt;&lt;/ul&gt; &lt;li&gt;A public constructor. Unless you subscribe to the ObjectDataSource's &lt;em&gt;ObjectCreating &lt;/em&gt;event in order to provide a custom instance before the binding calls are executed.  &lt;li&gt;A public method that returns the total number of rows not including the fetched-page size. This is only necessary if your ODS has EnablePaging set to true.  &lt;li&gt;Some attributes on the class or methods that do nothing but tell Visual Studio HEY! SHOW ME AS BINDABLE. Technically these are optional. &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Which, in the case of Northwind might look like:&lt;/p&gt;&lt;pre class="c#" name="code"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Linq;&lt;br /&gt;using Northwind.Model;&lt;br /&gt;&lt;br /&gt;namespace Northwind.DataBinding&lt;br /&gt;{&lt;br /&gt;    [DataObject(true)]&lt;br /&gt;    public class ProductQuerySource : IDisposable&lt;br /&gt;    {&lt;br /&gt;        private NorthwindDataContext _dataContext;&lt;br /&gt;        private bool _disposeContextWhenDone = false;&lt;br /&gt;        private int _count = 0;&lt;br /&gt;&lt;br /&gt;        public ProductQuerySource(NorthwindDataContext dataContext)&lt;br /&gt;        {&lt;br /&gt;            if (dataContext == null)&lt;br /&gt;                throw new ArgumentNullException("dataContext");&lt;br /&gt;            &lt;br /&gt;            _dataContext = dataContext;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public ProductQuerySource()&lt;br /&gt;            : this(new NorthwindDataContext())&lt;br /&gt;        {&lt;br /&gt;            _disposeContextWhenDone = true;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        [DataObjectMethod(DataObjectMethodType.Select)]&lt;br /&gt;        public IList&amp;lt;Product&amp;gt; FetchAll(int startAt, int pageSize)&lt;br /&gt;        {&lt;br /&gt;            _count = _dataContext.Products.Count();&lt;br /&gt;            &lt;br /&gt;            var query = _dataContext.Products.Skip(startAt).Take(pageSize).ToList();&lt;br /&gt;            &lt;br /&gt;            return query;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        [DataObjectMethod(DataObjectMethodType.Select)]&lt;br /&gt;        public IList&amp;lt;Product&amp;gt; FetchAll(int startAt, int pageSize, string sortExpression)&lt;br /&gt;        {&lt;br /&gt;            _count = _dataContext.Products.Count();&lt;br /&gt;&lt;br /&gt;            IQueryable&amp;lt;Product&amp;gt; products = _dataContext.Products;&lt;br /&gt;&lt;br /&gt;            if (!string.IsNullOrEmpty(sortExpression))&lt;br /&gt;                products = _dataContext.Products.OrderBy(sortExpression);&lt;br /&gt;            &lt;br /&gt;            return products.Skip(startAt).Take(pageSize).ToList();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public int GetCount()&lt;br /&gt;        {&lt;br /&gt;            return _count;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public void Dispose()&lt;br /&gt;        {&lt;br /&gt;            if (_disposeContextWhenDone)&lt;br /&gt;                _dataContext.Dispose();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;With our ObjectDataSource markup resembling&lt;/p&gt;&lt;pre class="xml" name="code"&gt;&amp;lt;asp:ObjectDataSource ID="odsNorthwindProducts" runat="server" &lt;br /&gt;        OldValuesParameterFormatString="original_{0}" &lt;br /&gt;        SelectMethod="FetchAll" TypeName="Northwind.DataBinding.ProductQuerySource"&lt;br /&gt;        EnablePaging="true"&lt;br /&gt;        MaximumRowsParameterName="pageSize" &lt;br /&gt;        StartRowIndexParameterName="startAt" &lt;br /&gt;        SelectCountMethod="GetCount" SortParameterName="sortExpression"&amp;gt;&lt;br /&gt;    &amp;lt;/asp:ObjectDataSource&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Link that sucker to a GridView with &lt;em&gt;AllowPaging&lt;/em&gt; and &lt;em&gt;AllowSorting&lt;/em&gt; both set to true and you'll get a grid displaying Products in which only the products currently being rendered are even returned from the database. Click on a column header to sort? Current paged fetched and sorted in database. Fantastic. Note that standard parameter-binding applies here as well, Fetch() could easily have a &lt;em&gt;categoryid &lt;/em&gt;parameter which might limit the results to all Products in that category. Since its all just methods on a class, our binding class can be tested using whatever the your testing strategy of choice happens to be.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Oh, but what about that pesky sorting? We can't sort a linq query by a string, can we? Well, yeah, normally that would be the case, but not to fear, because but by taking a bit of code based on &lt;a href="http://technoesis.wordpress.com/2008/03/03/linq-to-sql-dynamic-sorting-without-using-complete-dynamic-linq-libraries/"&gt;this&lt;/a&gt; post by Pradeep Mishra (which has alot of typos in the code there, beware) we'll be able to dynamically use those string sort expressions to invoke Linq's OrderBy and OrderByDescending methods. Which, in the case of Linq to Sql, will result in the respective ORDER BY clauses being added to the query once it is executed against the database.&lt;/p&gt;&lt;pre class="c#" name="code"&gt;using System;&lt;br /&gt;using System.Linq.Expressions;&lt;br /&gt;&lt;br /&gt;namespace System.Linq&lt;br /&gt;{&lt;br /&gt;    public static class LinqExtensions&lt;br /&gt;    {&lt;br /&gt;        public static IQueryable&amp;lt;TEntity&amp;gt; OrderBy&amp;lt;TEntity&amp;gt;(this IQueryable&amp;lt;TEntity&amp;gt; source, string sortExpression) where TEntity : class&lt;br /&gt;        {&lt;br /&gt;            if (string.IsNullOrEmpty(sortExpression))&lt;br /&gt;                return source; // nothing to sort on&lt;br /&gt;&lt;br /&gt;            var entityType = typeof(TEntity);&lt;br /&gt;            string ascSortMethodName = "OrderBy";&lt;br /&gt;            string descSortMethodName = "OrderByDescending";            &lt;br /&gt;            string[] sortExpressionParts = sortExpression.Split(' ');&lt;br /&gt;            string sortProperty = sortExpressionParts[0];&lt;br /&gt;            string sortMethod = ascSortMethodName;&lt;br /&gt;&lt;br /&gt;            if (sortExpressionParts.Length &amp;gt; 1 &amp;amp;&amp;amp; sortExpressionParts[1] == "DESC")&lt;br /&gt;                sortMethod = descSortMethodName;    &lt;br /&gt;&lt;br /&gt;            var property = entityType.GetProperty(sortProperty);&lt;br /&gt;            var parameter = Expression.Parameter(entityType, "p");&lt;br /&gt;            var propertyAccess = Expression.MakeMemberAccess(parameter, property);&lt;br /&gt;            var orderByExp = Expression.Lambda(propertyAccess, parameter);&lt;br /&gt;&lt;br /&gt;            MethodCallExpression resultExp = Expression.Call(&lt;br /&gt;                                                typeof(Queryable), &lt;br /&gt;                                                sortMethod, &lt;br /&gt;                                                new Type[] { entityType, property.PropertyType },&lt;br /&gt;                                                source.Expression, &lt;br /&gt;                                                Expression.Quote(orderByExp));&lt;br /&gt;&lt;br /&gt;            return source.Provider.CreateQuery&amp;lt;TEntity&amp;gt;(resultExp);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;So having that in place means we can have SortParameterName="sortDirection" in our ODS markup as well as the sortDirection string parameter on the binding method. Hello, server-side paging and sorting.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I should note that this sorting and paging isn’t unique to Linq To Sql- it applies to anything queryable by Linq. It's just that leveraging this approach with Linq To Sql yields for a more elegant sorting and paging solution when working with a database than some other the other switch-based or (god forbid) stored-procedure based approaches.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-3520209467341163036?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/3520209467341163036/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2011/07/linq-to-sql-and-objectdatasource-bff.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/3520209467341163036?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/3520209467341163036?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2011/07/linq-to-sql-and-objectdatasource-bff.html" title="Linq to Sql and ObjectDataSource: BFF" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEcAQ3o5eCp7ImA9WhZaFEU.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-8838351856874805130</id><published>2011-06-30T21:00:00.001-04:00</published><updated>2011-06-30T21:00:42.420-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-30T21:00:42.420-04:00</app:edited><title>Loving to Win / Hating to lose</title><content type="html">&lt;p&gt;Recently I was playing around with the new Asp.Net MVC3 bits, specifically around getting a working endpoint for getting push notifications from the Amazon Simple Notification Service (SNS). I spent most of the time fighting with IIS 7.5 just trying to get something other than a directory listing to show up. Of course it turned out to be &lt;a href="http://support.microsoft.com/kb/2023146"&gt;some obscure setting that had to be flipped&lt;/a&gt; that had nothing to do with MVC3. With deployment stories like that, it’s no wonder folks are leaving the .Net platform for others. A playful Sunday morning of coding turned sour because IIS won’t play nice.&lt;/p&gt; &lt;p&gt;It actually reminds of the recent NBA finals. Wait, here me out. I’m not a big pro basketball fan but I catch some sports radio here and there and I heard something that kind of stuck with me. The discussion was about Lebron James and how he had been struggling to close out games late in the fourth quarters when he is so talented and has so much talent around him. Then someone, a caller or one of the host pundits said something to this effect: Lebron loves to win. Kobe and Dirk and Durant and others &lt;em&gt;hate to lose&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;That concept shouldn’t be that foreign to anyone doing the whole agile thing. It’s built around the idea of success through failure. Fail early, adjust, and get better. Rinse, repeat.Have a continuous integration build that makes you smile when it runs without errors and 100% tests passing, but you don’t immediately drop everything and fix it when tests fail or someone checks in some broken code? You’re loving to win, but tolerant of losing.&lt;/p&gt; &lt;p&gt;Back to Microsoft. It seems like DevDiv is turning the corner on hating to lose. Most non-Microsofties would consider early versions of Entity Framework to be failures, even early versions of MVC, while promising, didn’t hit the spot for a lot of people.Now we’ve got EF Code-First, a more mature MVC, and Nuget, all big wins coming out of DevDiv. Then we’ve got the product teams which I assume are not part of DevDiv. The SharePoint teams and the TFS teams, even in 2010 are publishing APIs that are chock full of sealed classes, static methods, with no interfaces leaving any developer actually interested in unit testing against said API left out to dry. It’s really telling that MVC has &lt;a href="http://mvccontrib.codeplex.com/"&gt;projects adding bells and whistles&lt;/a&gt;, while TFS has projects that only exist to &lt;a href="http://tfsapiwrapper.codeplex.com/"&gt;wrap the untestable API itself&lt;/a&gt;. One’s winning, one’s losing. &lt;/p&gt; &lt;p&gt;Do &lt;em&gt;you &lt;/em&gt;hate to lose or love to win? What about your team? Your organization/company?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-8838351856874805130?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/8838351856874805130/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2011/06/loving-to-win-hating-to-lose.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/8838351856874805130?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/8838351856874805130?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2011/06/loving-to-win-hating-to-lose.html" title="Loving to Win / Hating to lose" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C04ARns5fyp7ImA9WhZVGUQ.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-7922158378956745652</id><published>2011-06-02T01:19:00.000-04:00</published><updated>2011-06-02T01:19:07.527-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-02T01:19:07.527-04:00</app:edited><title>Regarding the Real World</title><content type="html">I see this alot, lifer developers in big IT referencing what they do being contrary to 'the real world' where things like ajax, care towards user experience, advanced testing techniques, etc are considered commonplace. If I was a manager this would be a fireable offense.&lt;br /&gt;
&lt;br /&gt;
Just because you work in a big 'enterprise' on brownfield apps that haven't been touched since Net 1.1 days doesn't mean you can't improve it. Just because your organization is dysfunctional doesn't mean you cant make improvements in the code you see and write everyday. Using the excuse that you're not in the real world using bleeding edge stuff as a reason to basic techniques like unit testing and SOLID, patterns, etc, is just that: an excuse. And guess what? The so called 'real world' projects have problems too, but they're sucking it up and solving them. What are &lt;i&gt;you &lt;/i&gt;doing?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-7922158378956745652?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/7922158378956745652/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2011/06/regarding-real-world.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/7922158378956745652?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/7922158378956745652?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2011/06/regarding-real-world.html" title="Regarding the Real World" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0MAQHk9fCp7ImA9WhZWE0w.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-7817041353493028700</id><published>2011-05-11T17:26:00.000-04:00</published><updated>2011-05-13T16:44:01.764-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-13T16:44:01.764-04:00</app:edited><title>You are not your code</title><content type="html">&lt;p&gt;&lt;a href="http://wekeroad.com"&gt;Rob&lt;/a&gt; tweeted:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;This thread is a fucking embarrassment for all .NET developers (read toward the end) &lt;a href="http://groups.google.com/group/subsonicproject/browse_thread/thread/ee2d5f16dfed6766?hl=en"&gt;groups.google.com/group/subsonic…&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;And it is. Poor guy is having some performance problems with SubSonic compared to Entity Framework when loading 1 million rows in his application. Then he goes to say he’d rather quit than use inline SQL to get better performance.&lt;/p&gt; &lt;p&gt;Pretend you’re in that situation. Your building some analytic fat client application that shoves fancy dashboards in the faces of middle managers so they can maybe make better business decisions. Would &lt;em&gt;they&lt;/em&gt; care that you used a bit of inline SQL to gain some performance? Would &lt;em&gt;they &lt;/em&gt;care that you use an ORM? I’m going to go out on a limb and say that they wouldn’t. They want their dashboards and whiz bang analytics to work and work well and perform well. You know, the stuff that &lt;em&gt;you’re actually supposed to be delivering&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Im all for ORMs and clean code and patterns and SOLID and software craftsmanship but like most things, they’re best in moderation. There are exceptions to every piece of guidance/pattern/scenario out there.&lt;/p&gt; &lt;p&gt;An unwillingness to accept a given solution does not mean that the solution does not exist. Solve the right problems. You are not your code. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-7817041353493028700?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/7817041353493028700/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2011/05/you-are-not-your-code.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/7817041353493028700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/7817041353493028700?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2011/05/you-are-not-your-code.html" title="You are not your code" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEUDRHo6eyp7ImA9WhZSGEk.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-7128034808504870270</id><published>2011-04-03T11:57:00.000-04:00</published><updated>2011-04-03T11:57:55.413-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-03T11:57:55.413-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Reporting" /><category scheme="http://www.blogger.com/atom/ns#" term="WebForms" /><category scheme="http://www.blogger.com/atom/ns#" term="ReportViwer" /><title>Upgrading your Asp.Net reporting to ReportViewer 10.0.0.0</title><content type="html">&lt;p&gt;&lt;img style="display: inline; float: left" align="left" src="http://2.bp.blogspot.com/_vkAnhL7OH1E/TD_GMipSr4I/AAAAAAAAB9Y/DRhGfZByzrY/s1600/Tps_report.png" width="100" height="122"&gt;I recently had the &lt;s&gt;immense frustration&lt;/s&gt; distinct pleasure of upgrading a .Net 3.5 Asp.Net web forms application using client-side reports with the old and busted ReportViewer 8.0.0.0 to the new hotness ReportViewer 10.0.0.0 that ships with Visual Studio 2010. I thought it would be a simple update to the project references and a re-compile but unfortunately it turned out to be more involved. So for anyone else, here's the lowdown.&lt;br&gt;&lt;br&gt;1. Once you try to open .rdlc files in Visual Studio 2010 that were created with previous versions of Visual Studio, you'll be prompted to upgrade the file to RDL 2008 format, or else be relegated to viewing the file in the Visual Studio Xml editor. If you don't, then they'll be upgraded at runtime but you'll probably want to upgrade them anyways, and you’ll be forced to if you ever want to edit them in Visual Studio using the report designer.&lt;br&gt;&lt;br&gt;2. You'll obviously want to remove your old Microsoft.ReportViewer references and add new ones to the Microsoft.ReportViewer.WebForms 10.0.0.0 assembly. The same deployment model applies though. If you run the &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a941c6b2-64dd-4d03-9ca7-4017a0d164fd&amp;amp;displaylang=en"&gt;ReportViewer 2010 redistributable&lt;/a&gt; on both your development and production servers than you'll only have to reference the WebForms library. However, if you can't or don't want to do that, then you'll want to extract Microsoft.ReportViewer.WebForms.dll, Microsoft.ReportViewer.Common.dll, Microsoft.ReportViewer.ProcessingObjectModel all from the GAC (after running the redistributable obviously) and add file references to them. You'll also want to update your web.config, which is mostly updating the version string in all the settings related to Microsoft.ReportViewer. When in doubt, new up a blank Asp.Net web application, add a ReportViewer control from the toolbox onto Default.aspx and look at the web.config.You may want to do that anyways, especially if you’re moving to IIS7 as well as ReportViewer 10.&lt;br&gt;&lt;br&gt;3. Your existing aspx pages may not work after all this because ReportViewer 10.0.0.0 is much more asynchronous friendly and thus requires a ScriptManager control on the page now in order to function correctly. Fortunately, the orange screen of death that you get when you forget to do this is pretty self-explanatory.&lt;br&gt;&lt;br&gt;4. Your existing aspx pages may &lt;i&gt;still &lt;/i&gt;not work correctly because of a &lt;a href="http://blogs.msdn.com/b/brianhartman/archive/2010/11/16/the-invisible-reportviewer.aspx"&gt;bug with the Visible property&lt;/a&gt; on the ReportViewer 10 control. If you have pages where a ReportViewer is initially hidden, declaratively configured in the aspx markup, that is unhidden and rendered after some user input, you'll probably run in to this. You won't get an exception, just a blank report. If you view source, you'll see some text relating to a configuration error in the web.config. Ignore it, it's misleading. The workaround is to set the LocalReport.ReportPath (or LocalReport.ReportEmbeddedResource) just after you set Visible to true. It’s on &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/571085"&gt;Microsoft Connect&lt;/a&gt; already. 100% of the reports I had in the aforementioned web application worked this way and were affected by this. Not fun.&lt;/p&gt; &lt;p&gt;There is at least one other gotcha I ran into but it is not specific to ReportViewer 10 so I’ll cover that in a future post. Happy reporting.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-7128034808504870270?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/7128034808504870270/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2011/04/upgrading-your-aspnet-reporting-to.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/7128034808504870270?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/7128034808504870270?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2011/04/upgrading-your-aspnet-reporting-to.html" title="Upgrading your Asp.Net reporting to ReportViewer 10.0.0.0" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_vkAnhL7OH1E/TD_GMipSr4I/AAAAAAAAB9Y/DRhGfZByzrY/s72-c/Tps_report.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEcNR3gyfyp7ImA9WhZTGUk.&quot;"><id>tag:blogger.com,1999:blog-6589428958282783828.post-1961837116268041250</id><published>2011-03-24T00:48:00.001-04:00</published><updated>2011-03-24T00:48:16.697-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-24T00:48:16.697-04:00</app:edited><title>My blog is dead, long live my blog</title><content type="html">&lt;p&gt;Ok, trying this blog thing again. I had all of a small handful of posts in the previous iteration, which I may or may not bring over, and one draft from months ago. At least now I’m not spending a couple meals-at-Chipotle’s worth of dollars on hosting every month so said blog can languish in internet dust. Turns out blogspot is pretty decent, who knew? I really wanted to like dasblog, I really did. I really wanted to continue using a blog engine built on the .Net platform which I enjoy so much. I actually do still like dasblog, its just that setting it up on medium trust hosting and doing upgrades is so painful. Who wants to spend time looking at files in windiff anyways? I guess I’ve reached my old curmudgeon phase where I just want crap to work so I can get on with other things. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6589428958282783828-1961837116268041250?l=blog.invalidoperation.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.invalidoperation.com/feeds/1961837116268041250/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.invalidoperation.com/2011/03/my-blog-is-dead-long-live-my-blog.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/1961837116268041250?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6589428958282783828/posts/default/1961837116268041250?v=2" /><link rel="alternate" type="text/html" href="http://blog.invalidoperation.com/2011/03/my-blog-is-dead-long-live-my-blog.html" title="My blog is dead, long live my blog" /><author><name>Ray</name><uri>http://www.blogger.com/profile/11494779418161460684</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry></feed>

