/src/Amptools/Public/labels/CSharp.aspx
ASP.NET | 882 lines | 655 code | 227 blank | 0 comment | 79 complexity | 203851361b6af3e1f5b5d4a65efea232 MD5 | raw file
1<%@ Page Title="amptools.net" Language="C#" MasterPageFile="~/App/Views/Layouts/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="System.Web.Mvc.ViewPage" %> 2<asp:Content ID="Content2" ContentPlaceHolderID="Head" runat="server"> 3 <link href='/Content/default/css/syntax-highlighter.css' rel="stylesheet" type="text/css" /> 4 <link rel="alternate" type="application/rss+xml" title="amptools.net - RSS" href="http://feeds.feedburner.com/amptoolsnet" /> 5 <link rel="service.post" type="application/atom+xml" title="amptools.net - Atom" href="http://www.blogger.com/feeds/7043853799247804655/posts/default" /> 6 <link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://www.blogger.com/rsd.g?blogID=7043853799247804655" /> 7 <style type="text/css"> 8 @import url("http://www.blogger.com/css/blog_controls.css"); 9 @import url("http://www.blogger.com/dyn-css/authorization.css?targetBlogID=7043853799247804655"); 10 </style> 11 12 <script type="text/javascript" src="http://www.blogger.com/js/backlink.js"></script> 13 <script type="text/javascript" src="http://www.blogger.com/js/backlink_control.js"></script> 14 <script type="text/javascript">var BL_backlinkURL = "http://www.blogger.com/dyn-js/backlink_count.js";var BL_blogId = "7043853799247804655";</script> 15</asp:Content> 16 17<asp:Content ID="Content3" ContentPlaceHolderID="Javascript" runat="server"> 18 <script type="text/javascript" src="~/javascripts/prototype.js"></script> 19 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shCore.js"></script> 20 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushCSharp.js"></script> 21 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushRuby.js"></script> 22 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushJScript.js"></script> 23 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushCss.js"></script> 24 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushSql.js"></script> 25 <script type="text/javascript" src="~/javascripts/syntax-highlighter/shBrushXml.js"></script> 26 <script type="text/javascript"> 27 //<[CDATA[ 28 dp.SyntaxHighlighter.HighlightAll('code'); 29 //]]> 30 </script> 31</asp:Content> 32<asp:Content ID="Content1" ContentPlaceHolderID="main" runat="server"> 33 34 35 <div class="left"> 36 <h2 class="silver"> 37 "Working on the complexity that is always indirectly implied by simpilicity." 38 </h2> 39 40 41 42 <h2 class="blog-title"><a name="1099928894407582088"></a> 43 44 Simple Log in Amplify 45 46 <span class="blog-byline"> 47 by: michael herndon, at: 11/02/2008 11:54:00 PM 48 </span> 49 50 </h2> 51 <div class="blog-content"> 52 <p>As many people know rails has a simple logger inside the framework which really only outputs to the console. This comes in handy to see SQL output of your models, benchmarks and other cool little things inside the rails framework.  </p> <p>Of course people in the .Net realm tend to want things that scale and yet simplified for them.  So output only to the console won't fly in larger projects.  There is log4net, but you don't want to have it tightly coupled to the system, this caused an issue to one project that I worked on while still working for <a href="http://www.vivussoftware.com">Vivus Software</a> before I came <a href="http://www.opensourceconnections.com">OSC</a>. Where the framework and project both expected a certain version of Log4Net and there was no wrapper to put something else in place if need be.  </p> <span id="more-0"></span> <p>So the solution was to Build small static Log class, that takes a list of an interface ILog (different than log4net's) and then use that interface to build a wrapper around using the root Logger for log4net. This way people can still build their own loggers for amplify or build their own Appenders for Log4Net and amplify will still be able to leverage this. Of course there is also conditional symbol LOG4NET in amplify if you wish to build the amplify framework without any dependency on the log4net library.   </p> <p>To me this is more like the Console.WriteLine that is needed for a class library vs what log4net is typically used for in an application where it also spits out the type information of a class. To help with the testing using mock object is the <a href="http://code.google.com/p/moq/" rel="tag">Moq (Mock You)</a> which uses the Lambda expression and gets rid of all that crazy record/playback junk to which I loathe.  </p> <pre class="code csharp"> public void Test() 53 { 54 var id = 0; 55 Log.Sql("SELECT * FROM test"); 56 Log.Debug("The id is {0} ", id); 57 } 58 59 60 [It(Order = 2), Should("have a debug method that logs debug statements")] 61 public void Debug() 62 { 63 var calls = new List<string>(); 64 var log = CreateMockLog(); 65 66 log.Expect(o => o.Debug(Moq.It.IsAny<string>(), null)) 67 .Callback((string s, object[] args) => { calls.Add(s); }); 68 69 calls.Count.ShouldBe(0); 70 71 // simple and easily called from anywhere... and lets you 72 // format messages like 73 // Log.Debug("item id: {0} could not be saved", id); 74 Log.Debug("debug", null); 75 calls.Count.ShouldBe(1); 76 calls.Contains("debug").ShouldBeTrue(); 77 78 Log.IsDebug = false; 79 80 // its turned off so it won't output anything 81 Log.Debug("debug", null); 82 calls.Count.ShouldBe(1); 83 84 Log.IsDebug = true; 85 } 86 87 private static Mock<ILog> CreateMockLog() 88 { 89 var log = new Mock<ILog>(); 90 Log.Loggers.Clear(); 91 Log.Loggers.Add(log.Object); 92 return log; 93 } 94</pre> 95 96<p>Though keep in mind, one of the more trickier things to mock is the use of a method with the "params" keyword. I had to used a callback that you pass in an object array (object[] args) and I passed in null, otherwise the callback would not fire, and Lambdas don't allow the "params" keyword. Once that was figured out, I was able to use moq successfully to test the Log class successfully. </p> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/BHAG.aspx">BHAG</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/Mock Objects.aspx">Mock Objects</a>, <a rel='tag' href="http://www.amptools.net/labels/Moq.aspx">Moq</a>, <a rel='tag' href="http://www.amptools.net/labels/Unit Testing.aspx">Unit Testing</a></p> 97 </div> 98 <div class="blog-footer"> 99 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=1099928894407582088"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=1099928894407582088;><span style="text-transform:lowercase">0 Comments</span></a> 100 101 <a class="comment-link" href="http://www.amptools.net/2008/11/simple-log-in-amplify.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 102 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=1099928894407582088" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 103 104 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 105 </div> 106 107 108 109 <h2 class="blog-title"><a name="3448672103322818552"></a> 110 111 Gallio and Mb-Unit release v3.0.4 112 113 <span class="blog-byline"> 114 by: michael herndon, at: 10/29/2008 02:11:00 AM 115 </span> 116 117 </h2> 118 <div class="blog-content"> 119 <p>You can find many of the new <a href="http://blog.bits-in-motion.com/2008/10/announcing-gallio-and-mbunit-v304.html ">features over at Jeff Brown's blog</a>.  Some of the cooler features of note is the integration with the visual studio testing system, wrapping testing for exceptions into a delegate, and data store called Ambient, in which you can store state for your tests.  I've integrated this into amplify which is again, now on <a href="http://github.com/michaelherndon/amplify/tree/master">GitHub</a>. I did run into a few lil issues when setting this up though....</p> <span id="more-1"></span> <p>The biggest issue was finding out how to turn a project into a test project in order to get the visual studio integration working for Gallio. Basically you need to make modifications to the .csproj file and add an XML element of <ProjectTypeGuids> into the first <PropertyGroup> of the file.  </p> <pre class="code xml"><ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB}; 120{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 121</ProjectTypeGuids></pre> 122 123<p>After this, I could get the Gallio tests showing up in visual studio. </p> 124 125<p><a href="http://lh3.ggpht.com/amptools/SQf-bZnOv5I/AAAAAAAAABM/xPj4ncLlA3g/s1600-h/Gallio-Test-View%5B2%5D.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="212" alt="Gallio-Test-View" src="http://lh3.ggpht.com/amptools/SQf-b1n8cMI/AAAAAAAAABU/f0_tzJSs_Lg/Gallio-Test-View_thumb.png?imgmax=800" width="244" border="0" /></a> </p> 126 127<p>Now this coupled with <a href="http://testdriven.net/" rel="tag">Test Driven .Net</a> really helps with the testing process especially since with certain versions of Visual Studio, Test Driven .Net will let you run visual studio's code coverage with Gallio. </p> 128 129<p><a href="http://lh6.ggpht.com/amptools/SQf-cYepypI/AAAAAAAAABY/2DfBfKGZbZY/s1600-h/CodeCoverage%5B2%5D.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="207" alt="CodeCoverage" src="http://lh5.ggpht.com/amptools/SQf-cwXSDSI/AAAAAAAAABc/i2MQj8jhAQU/CodeCoverage_thumb.png?imgmax=800" width="244" border="0" /></a> </p> 130 131<p>Again, one of the cooler features was the improvements to Mb-Unit's Asserts (which did change the API, but its all good, cause I wrap the Asserts that I use in BDD style mixin Methods, so I just need to change them in one place). The one really change of note would be adding Assert.Throw and Assert.Throw<T>, to which you can wrap throwing an exception into a delegate.</p> 132 133<p><a href="http://lh6.ggpht.com/amptools/SQf-di2keqI/AAAAAAAAABg/KCLE5wy_nU4/s1600-h/WrappingExceptions%5B2%5D.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="178" alt="WrappingExceptions" src="http://lh3.ggpht.com/amptools/SQf-eB-bggI/AAAAAAAAABk/Tl816nR7vkw/WrappingExceptions_thumb.png?imgmax=800" width="244" border="0" /></a> </p> 134 135<p>All in all nice improvements to both Gallio and Mb-Unit, which are now incorporated into amplify. </p> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/BDD.aspx">BDD</a>, <a rel='tag' href="http://www.amptools.net/labels/BHAG.aspx">BHAG</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/Gallio.aspx">Gallio</a>, <a rel='tag' href="http://www.amptools.net/labels/Mb-Unit.aspx">Mb-Unit</a>, <a rel='tag' href="http://www.amptools.net/labels/Mixins.aspx">Mixins</a>, <a rel='tag' href="http://www.amptools.net/labels/Unit Testing.aspx">Unit Testing</a></p> 136 </div> 137 <div class="blog-footer"> 138 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=3448672103322818552"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=3448672103322818552;><span style="text-transform:lowercase">0 Comments</span></a> 139 140 <a class="comment-link" href="http://www.amptools.net/2008/10/gallio-and-mb-unit-release-v304.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 141 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=3448672103322818552" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 142 143 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 144 </div> 145 146 147 148 <h2 class="blog-title"><a name="1045031666772907229"></a> 149 150 Getting the |DataDirectory| folder in C sharp 151 152 <span class="blog-byline"> 153 by: michael herndon, at: 8/14/2008 02:19:00 PM 154 </span> 155 156 </h2> 157 <div class="blog-content"> 158 <p>One of the cool things about sql server express's connection strings is the ability to relatively path database files for sql express databases. Often one might see something in the connection string that looks like " AttachDbFilename=|DataDirectory|\file.mdf ". The pipes and DataDirectory is parsed to equate to a relative data directory file path that changes depending on the application type (i.e. an application deployed by click once, vs an application that is installed to a folder). </p> 159 160<p>However sometimes you might want to know where that data directory is, like in my case, I want to take a look at a connection string and attempt to create a database based off the connection string in order to speed up development using database migrations. This could also come in handy deploying small applications. </p> 161 162<p>So after some research via google, I found <a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=702378&SiteID=1">this gem on msdn about where the DataDirectory is</a>, though not guaranteed to be accurate. It basically follows 3 simple hierarchal rules. If the AppDomain.SetData method has been used, then the directory is set there. Otherwise if the application is a click once application the data directory is set or its in the application root folder. </p> <p>So below is what the code might possibly look like in order to get the applications data directory no matter what type of application it is and it gives you ability to set the DataDirectory as well. </p> <p></p> 163 164<pre class="code csharp">namespace Amplify 165{ 166 using System; 167 using System.Configuration; 168 using System.Collections.Generic; 169 using System.Collections.Specialized; 170 using System.Deployment; 171 using System.Deployment.Application; 172 using System.IO; 173 using System.Text; 174 using System.Reflection; 175 using System.Web; 176 177 public class ApplicationContext { 178 179 private static NameValueContext s_properties; 180 181 182 public static bool IsWebsite { get; internal set; } 183 184 static ApplicationContext() 185 { 186 IsWebsite = (System.Web.HttpContext.Current != null); 187 188 } 189 190 public static string DataDirectory 191 { 192 get 193 { 194 string dataDirectory = GetProperty("DataDirectory") as string; 195 196 if (string.IsNullOrEmpty(dataDirectory)) 197 { 198 dataDirectory = AppDomain 199 .CurrentDomain.GetData("DataDirectory") as string; 200 201 if (dataDirectory == null) 202 { 203 if (ApplicationDeployment.IsNetworkDeployed) 204 dataDirectory = ApplicationDeployment 205 .CurrentDeployment.DataDirectory; 206 else 207 dataDirectory = Path.GetDirectoryName( 208 Assembly.GetExecutingAssembly() 209 .GetName().CodeBase); 210 } 211 dataDirectory = dataDirectory.Replace(@"file:\", ""); 212 SetProperty("DataDirectory", dataDirectory); 213 } 214 return dataDirectory; 215 } 216 set 217 { 218 string dataDirectory = GetProperty("DataDirectory") as string; 219 value = value.Replace(@"file:\", value); 220 221 if (!System.IO.Directory.Exists(dataDirectory)) 222 System.IO.Directory.CreateDirectory(dataDirectory); 223 224 SetProperty("DataDirectory", value); 225 AppDomain.CurrentDomain.SetData("DataDirectory", value); 226 } 227 } 228 229 230 public static object GetProperty(string propertyName) 231 { 232 if (IsWebsite) 233 return HttpContext.Current.Application[propertyName]; 234 else 235 return Context[propertyName]; 236 } 237 238 239 public static void SetProperty(string propertyName, object value) 240 { 241 if (IsWebsite) 242 HttpContext.Current.Application[propertyName] = value; 243 else 244 Context[propertyName] = value; 245 } 246 247 private static NameValueContext Context 248 { 249 get 250 { 251 if (s_properties == null) 252 s_properties = new NameValueContext(); 253 return s_properties; 254 } 255 } 256 } 257}</pre><p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a></p> 258 </div> 259 <div class="blog-footer"> 260 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=1045031666772907229"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=1045031666772907229;><span style="text-transform:lowercase">0 Comments</span></a> 261 262 <a class="comment-link" href="http://www.amptools.net/2008/08/getting-datadirectory-folder-in-c-sharp.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 263 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=1045031666772907229" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 264 265 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 266 </div> 267 268 269 270 <h2 class="blog-title"><a name="458120713693871790"></a> 271 272 Amplify's WCF Twitter API Client Library v0.2 273 274 <span class="blog-byline"> 275 by: michael herndon, at: 7/28/2008 12:33:00 AM 276 </span> 277 278 </h2> 279 <div class="blog-content"> 280 <p>After some playing around with WCF and Flickr, I decided to move everything internally for the twitter library to use WCF with it's <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.aspx">ServiceContract</a>.  It was more of a pain that initially thought it would be. WCF is amazingly customizable but still has a couple of downfalls thanks to REST and people not writing their API for all technologies.  </p> <p>The biggest issue is that Twitter throws an Http 403 unknown exception when you call a page and something is incorrect in the url.  Well with WCF, it throws a <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.security.messagesecurityexception.aspx">System.ServiceModel.Security.MessageSecurityException</a>, due to the url returning a status code other than 200, and it wraps the inner exceptions inside of that. </p> <p>I'm sure there is a better way to get around this, but each proxy call is now wrapped by a try/catch in the client class methods in order to check for the <a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.security.messagesecurityexception.aspx">MessageSecurityException</a>, then it checks the inner exception and determines if twitter sent back a response error message. If it does the library now throws a twitter exception with error information, otherwise you would only see the WCF exception that would mask the real issue.  </p> <p>Also I renamed the "Service" classes to "Client" seeing that is the proper term for them.  The tests are now updated as well to reflect the changes.  The tests are a good way of seeing of how to use the library. Last but not least, methods now return arrays instead of lists in order to be more REST friendly. </p> <p></p> <pre class="code csharp">using Amplify.Twitter; 281using System.Security; 282 283// ... stuff 284 285public void Test() 286{ 287 try { 288 string temp = "password"; 289 290 Twitter.SetCredentials("Username", temp); 291 292 StatusClient client = Twitter.CreateStatusClient(); 293 // or StatusClient client = new StatusClient("Username", temp); 294 295 Status[] tweets = service.GetUserTimeline(); 296 } catch (TwitterException ex) { 297 Log.Write(ex.ToString()); // write the twitter rest error. 298 } 299 300}</pre> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/BHAG.aspx">BHAG</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/JSON.aspx">JSON</a>, <a rel='tag' href="http://www.amptools.net/labels/REST.aspx">REST</a>, <a rel='tag' href="http://www.amptools.net/labels/Twitter.aspx">Twitter</a>, <a rel='tag' href="http://www.amptools.net/labels/WCF.aspx">WCF</a></p> 301 </div> 302 <div class="blog-footer"> 303 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=458120713693871790"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=458120713693871790;><span style="text-transform:lowercase">2 Comments</span></a> 304 305 <a class="comment-link" href="http://www.amptools.net/2008/07/amplify-wcf-twitter-api-client-library.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 306 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=458120713693871790" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 307 308 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 309 </div> 310 311 312 313 <h2 class="blog-title"><a name="6391037880199004989"></a> 314 315 Use C# to determine where and what version of java is installed 316 317 <span class="blog-byline"> 318 by: michael herndon, at: 7/22/2008 08:56:00 AM 319 </span> 320 321 </h2> 322 <div class="blog-content"> 323 <p>While writing an MsBuild Task that is calling a jar file, there was a need to find out information on the java runtime on the local machine, otherwise when I do publish the task, the developer would be required to install a specific version of java in a specific location.  That kind of thing just doesn't fly if you're writing on a 64 bit machine due to having dual "Program Files" folders, one for 64 bit programs, the other for x86.  Not only that, it really increases complexity to the end user/developer who might want to use the MsBuild Task. </p> <p>So after poking around in the registry, I found out there was information about the Java Runtime, including which version is currently the default, and where the file path is. I wrote a singleton class that looks at the registry and grabs that information.  Though usually singleton generally only checks to see if the instance is null and then instantiates it, the code below checks the registry during the "Get" method. </p> <pre class="code csharp">namespace Amplify.Tasks 324{ 325 using System; 326 using System.Collections.Generic; 327 using System.Linq; 328 using System.Text; 329 330 using Microsoft.Win32; 331 332 public class JavaInfo 333 { 334 private static JavaInfo instance = null; 335 336 protected JavaInfo() 337 { 338 this.CurrentVersion = ""; 339 this.Installed = false; 340 this.Path = ""; 341 } 342 343 public string CurrentVersion { get; set; } 344 345 public bool Installed { get; set; } 346 347 public string Path { get; set; } 348 349 350 public static JavaInfo Get() 351 { 352 if (instance == null) 353 { 354 RegistryKey key = Registry.LocalMachine; 355 JavaInfo info = new JavaInfo(); 356 357 string location = @"Software\JavaSoft\Java Runtime Environment"; 358 RegistryKey environment = key.OpenSubKey(location); 359 if (environment != null) 360 { 361 362 info.Installed = true; 363 object value = environment.GetValue("CurrentVersion"); 364 if (value != null) 365 { 366 info.CurrentVersion = value.ToString(); 367 RegistryKey currentVersion = environment.OpenSubKey(info.CurrentVersion); 368 if (currentVersion != null) 369 { 370 value = currentVersion.GetValue("JavaHome"); 371 372 if (value != null) 373 info.Path = value.ToString(); 374 } 375 } 376 } 377 378 instance = info; 379 } 380 381 return instance; 382 } 383 } 384}</pre> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/Java.aspx">Java</a></p> 385 </div> 386 <div class="blog-footer"> 387 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=6391037880199004989"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=6391037880199004989;><span style="text-transform:lowercase">0 Comments</span></a> 388 389 <a class="comment-link" href="http://www.amptools.net/2008/07/use-c-to-determine-where-and-what.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 390 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=6391037880199004989" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 391 392 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 393 </div> 394 395 396 397 <h2 class="blog-title"><a name="8164722880411458481"></a> 398 399 Using WCF to access the Flickr JSON API 400 401 <span class="blog-byline"> 402 by: michael herndon, at: 7/17/2008 06:40:00 AM 403 </span> 404 405 </h2> 406 <div class="blog-content"> 407 <p>Even though there are quite a few opensource .Net libraries REST API out there, and a really impressive one for Flickr, they tend to never evolve or fork to use the newer framework technologies.  I think its great that they support 1.0, 2.0, and mono, but why not fork and support WCF?  I think part of the problem that .Net 3.5 use is not wide spread as it should be is not only information overload and bad naming for extension libraries, but also lack of opensource support to provide libraries and basis for current technology.  </p> <p>Flickr tends to be a little more tricky to use when calling it than some other REST APIs. WCF is a cool technology, but needs to be massaged when using it with Flickr due to a couple of gotchas and not so obvious things about WCF. In order to use Flickr, you need to register for an api_key and a shared secret code which is used to create an MD5 hash. You also need to create that MD5 each time you call a method, using the url parameters in a certain way. </p> <p>There are also a few not so obvious factors about using the JSON part of Flickr. All of the .Net libraries I've seen so far, use XML. While C# is king of parsing  XML, JSON tends to be more compact, which means less expense over the wire, though it might mean more time parsing once on the developers end point. So there are tradeoffs to using it. </p> <p>When I created the classes needed to use WCF to call Flickr, I have the actual "DataContract" object (DTO, Data Transfer Object), A Hash (Dictionary<string, object>) for adding the parameters to create the MD5 signature, A base class for creating the WCF proxy, a custom "WebContentTypeMapper", The "ServiceContract" interface, the actual "Client class", and a mixins class for creating the MD5. </p> <p>Here are some of the gotchas that I ran into while getting WCF to work with Flickr. </p> <p></p> <ol> <li>Flickr makes you create a md5 hash to send with every call for ALL parameters in alphabetical order using your "Shared Secret" Code as part of the md5.   </li> <li>Flickr's Json response "Content-Type" header is sent not as "application/json" but as "text/plain" which equates to "Raw" in WCF lingo.  </li> <li>The response object is wrapped and not obvious when it comes to json how the DataContract object should be formed.  </li> <li>Flickr will wrap the json response in a javascript function unless you pass in the parameter "nojsoncallback=1" </li> </ol> <p>To get around number one, I created an extension method that takes a Hash (Dictionary<string, object>) and adds method that converts the parameters into a MD5 string. </p> <pre class="code csharp">namespace Amplify.Linq 408{ 409 using System; 410 using System.Collections.Generic; 411 using System.Linq; 412 using System.Text; 413 414#if STANDALONE 415 public class Hash : Dictionary<string, object> 416 { 417 418 419 420 421 } 422#endif 423} 424// different file 425 426namespace Amplify.Linq 427{ 428 using System; 429 using System.Collections.Generic; 430 using System.Linq; 431 using System.Security.Cryptography; 432 using System.Text; 433 434 using Amplify.Linq; 435 436 public static class Mixins 437 { 438 439 440 441 public static string ToMD5(this Hash obj, string secret) 442 { 443 var query = from item in obj 444 orderby item.Key ascending 445 select item.Key + item.Value.ToString(); 446 447 StringBuilder builder = new StringBuilder(secret, 2048); 448 449 foreach (string item in query) 450 builder.Append(item); 451 452 MD5CryptoServiceProvider crypto = new MD5CryptoServiceProvider(); 453 byte[] bytes = Encoding.UTF8.GetBytes(builder.ToString()); 454 byte[] hashedBytes = crypto.ComputeHash(bytes, 0, bytes.Length); 455 return BitConverter.ToString(hashedBytes).Replace("-", "").ToLower(); 456 } 457 458 } 459}</pre> 460 461<p>Well Gotcha number two, took a bit of research to figure it out. The error I got was that it was looking for Json or XML but could not do anything with "Raw". So the solution is to create a custom binding with a custom WebContentTypeManager. </p> 462 463<pre class="code csharp">namespace Amplify.Flickr 464{ 465 using System.ServiceModel; 466 using System.ServiceModel.Channels; 467 using System.Runtime.Serialization; 468 using System.ServiceModel.Web; 469 470 public class JsonContentMapper : WebContentTypeMapper 471 { 472 public override WebContentFormat GetMessageFormatForContentType(string contentType) 473 { 474 return WebContentFormat.Json; 475 } 476 } 477} 478 479// different file 480 481namespace Amplify.Flickr 482{ 483 using System; 484 using System.Collections.Generic; 485 using System.Linq; 486 using System.Text; 487 using System.ServiceModel; 488 using System.ServiceModel.Channels; 489 using System.ServiceModel.Description; 490 using System.ServiceModel.Web; 491 492 using Amplify.Linq; 493 494 public class FlickrClient<T> 495 { 496 protected string Secret { get; set; } 497 498 protected string Key { get; set; } 499 500 protected string Token { get; set; } 501 502 protected string Url { get; set; } 503 504 protected T Proxy { get; set; } 505 506 507 public FlickrClient(string key, string secret) 508 { 509 this.Key = key; 510 this.Secret = secret; 511 this.Url = "http://api.flickr.com/services/rest"; 512 this.Proxy = this.InitializeProxy(); 513 } 514 515 public FlickrClient(string key, string secret, string token) 516 :this(key, secret) 517 { 518 this.Token = token; 519 } 520 521 protected virtual T InitializeProxy() 522 { 523 // using custom wrapper 524 CustomBinding binding = new CustomBinding(new WebHttpBinding()); 525 WebMessageEncodingBindingElement property = binding.Elements.Find<WebMessageEncodingBindingElement>(); 526 property.ContentTypeMapper = new JsonContentMapper(); 527 528 529 ChannelFactory<T> channel = new ChannelFactory<T>( 530 binding, this.Url); 531 532 channel.Endpoint.Behaviors.Add( new WebHttpBehavior()); 533 return channel.CreateChannel(); 534 } 535 536 } 537}</pre> 538 539<p>The 3rd issue, to know that all objects are wrapped in a "Response" object. To create a DataContract for the getFrob method on flickr, it took looking at the json to see what it was returning. The object below is the basic form of the Json object that is returned, it also includes the properties in case an error object is returned. </p> 540 541<pre class="code csharp"> using System; 542 using System.Collections.Generic; 543 using System.Linq; 544 using System.Text; 545 using System.Runtime.Serialization; 546 547 [DataContract] 548 public class FrobResponse 549 { 550 [DataMember(Name = "frob")] 551 public JsonObject Frob { get; set; } 552 553 [DataContract(Name = "frob")] 554 public class JsonObject 555 { 556 [DataMember(Name = "_content")] 557 public string Content { get; set; } 558 559 } 560 561 [DataMember(Name = "stat")] 562 public string Status { get; set; } 563 564 [DataMember(Name = "code")] 565 public int Code { get; set; } 566 567 [DataMember(Name = "message")] 568 public string Message { get; set; } 569 } 570 571 // different file 572 573 574 using System; 575 using System.Collections.Generic; 576 using System.Linq; 577 using System.Text; 578 using System.ServiceModel; 579 using System.ServiceModel.Web; 580 581 [ServiceContract] 582 public interface IAuthClient 583 { 584 [OperationContract, 585 WebInvoke( 586 UriTemplate = "/?method=flickr.auth.getFrob&format=json&nojsoncallback=1&api_key={key}&api_sig={signature}", 587 ResponseFormat = WebMessageFormat.Json, 588 BodyStyle = WebMessageBodyStyle.Bare)] 589 FrobResponse GetFrob(string signature, string key); 590 591 [OperationContract, 592 WebInvoke( 593 UriTemplate = "/?method=flickr.auth.getToken&format=json&nojsoncallback=1&api_key={key}&frob={frob}&api_sig={signature}", 594 ResponseFormat = WebMessageFormat.Json, 595 BodyStyle = WebMessageBodyStyle.WrappedResponse)] 596 Auth GetToken(string signature, string key, string frob); 597 } 598 599 600 // the actual client class. 601 602 using System; 603 using System.Collections.Generic; 604 using System.Linq; 605 using System.Text; 606 607 using Amplify.Linq; 608 609 610 public class AuthClient : FlickrClient<IAuthClient> 611 { 612 613 public AuthClient(string key, string secret) 614 :base(key, secret) 615 { } 616 617 public AuthClient(string key, string secret, string token) 618 :base(key, secret, token) 619 { } 620 621 public string GetFrob() 622 { 623 string md5 = new Hash() { 624 {"api_key", this.Key}, 625 {"format", "json"}, 626 {"method", "flickr.auth.getFrob"}, 627 {"nojsoncallback", 1} 628 }.ToMD5(this.Secret); 629 630 FrobResponse response = this.Proxy.GetFrob(md5, this.Key); 631 if (response.Code > 0) 632 throw new Exception(response.Message); 633 634 return response.Frob.Content; 635 } 636 }</pre> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/Flickr.aspx">Flickr</a>, <a rel='tag' href="http://www.amptools.net/labels/JSON.aspx">JSON</a>, <a rel='tag' href="http://www.amptools.net/labels/REST.aspx">REST</a>, <a rel='tag' href="http://www.amptools.net/labels/WCF.aspx">WCF</a></p> 637 </div> 638 <div class="blog-footer"> 639 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=8164722880411458481"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=8164722880411458481;><span style="text-transform:lowercase">0 Comments</span></a> 640 641 <a class="comment-link" href="http://www.amptools.net/2008/07/using-wcf-to-access-flickr-json-api.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 642 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=8164722880411458481" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 643 644 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 645 </div> 646 647 648 649 <h2 class="blog-title"><a name="1989566401714559482"></a> 650 651 Sample Mixins for HttpRequestBase to use with Asp.Net MVC 652 653 <span class="blog-byline"> 654 by: michael herndon, at: 7/16/2008 12:40:00 AM 655 </span> 656 657 </h2> 658 <div class="blog-content"> 659 <p>Being a semi avid user of rails for my day job, you tend to miss a couple of things that rails has that is not in Asp.Net's MVC framework. It is a great start and the control over the html (minus laziness of whoever ever developed their "Html.DropDownList" extension method, grrr INDENT YOUR NEW LINES!!), is much greater than what webforms gives you. One of the missing things that I miss is the request.xhr?, request.post?, etc methods that end to be helpful when deciding if this is an AJAX call or an actual action call to return the correct page. </p> <p>So how do you determine if the request is an ajax request or just a regular page request. What about enforcing that a page is SSL?  What about doing different things depending if the request is a GET or POST?  </p> <p>So after some googling about headers, rails, and such: here are the first go around of extension methods for HttpRequestBase that should come in handy. </p> <pre class="code csharp">public static class ControllerMixins 660{ 661 662 public static bool IsPost(this HttpRequestBase obj) 663 { 664 return obj.Headers["REQUEST_METHOD"].ToLower() == "post"; 665 } 666 667 public static bool IsGet(this HttpRequestBase obj) 668 { 669 return obj.Headers["REQUEST_METHOD"].ToLower() == "get"; 670 } 671 672 public static bool IsXhr(this HttpRequestBase obj) 673 { 674 string value = obj.Headers["HTTP_X_REQUESTED_WITH"]; 675 return (!string.IsNullOrEmpty(value) && value.ToLower() == "xmlhttprequest"); 676 } 677 678 public static bool IsSSL(this HttpRequestBase obj) 679 { 680 return obj.Headers["HTTPS"] == "on" || 681 obj.Headers["'HTTP_X_FORWARDED_PROTO'"] == "https"; 682 } 683}</pre> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Asp.Net.aspx">Asp.Net</a>, <a rel='tag' href="http://www.amptools.net/labels/Asp.Net Mvc.aspx">Asp.Net Mvc</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/Code.aspx">Code</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/Mixins.aspx">Mixins</a></p> 684 </div> 685 <div class="blog-footer"> 686 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=1989566401714559482"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=1989566401714559482;><span style="text-transform:lowercase">0 Comments</span></a> 687 688 <a class="comment-link" href="http://www.amptools.net/2008/07/sample-mixins-for-httprequestbase-to.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 689 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=1989566401714559482" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 690 691 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 692 </div> 693 694 695 696 <h2 class="blog-title"><a name="3907268195622759157"></a> 697 698 Amplify's TwitterN, Yet Another C# Twitter REST API Library 699 700 <span class="blog-byline"> 701 by: michael herndon, at: 7/13/2008 03:08:00 PM 702 </span> 703 704 </h2> 705 <div class="blog-content"> 706 <p><a href="http://code.google.com/p/twittern">http://code.google.com/p/twittern</a></p> <p>I put together a C# twitter library that uses WCF's <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx">DataContract</a> & <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx">DataMembers</a> and .Net 3.5's <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx">DataContractJsonSerializer</a>.  Its currently in alpha stage, as I need to finish writing the tests, documentation and make a simple WPF client for twitter.  I needed a twitter library for a personal "secret" project of mine and found that most twitter libraries do not keep up with the twitter API and break when using them. Plus they tend to go to great lengths when parsing the xml.  Unfortunately I do not know if this will work on mono yet. It seems that they have "<a href="http://www.mono-project.com/WCF">Olive</a>", which is mono's version of WCF and I've seen where they have a path for the "DataContractJsonSerializer".  If there are any one familiar enough with mono, please by all means use the code, join the project.  </p> <p>One design decision that I made was to use Json rather than xml as its more compact and less data to transfer.  I used WCF because with DataContract & DataMembers you can parse Json and you can name your properties the property way with Pascal Case properties and then tell wcf what attributes of json they represent. This way you don't have properties that look like ruby like "screen_name" or  "profile_sidebar_border_color" in your <a href="http://martinfowler.com/eaaCatalog/dataTransferObject.html">Data Transfer Object</a> in order to deserialize the Json response from twitter. </p> <p> </p> <p>A basic sample of how to use the library is below. </p> <pre class="code csharp"> 707 708using Amplify.Twitter; 709using System.Security; 710 711// ... stuff 712 713public void Test() 714{ 715 SecureString password = new SecureString(); 716 string temp = "password"; 717 for (var i = 0; i < temp.Length; i++) 718 password.AppendChar(temp[i]); 719 720 password.MakeReadOnly(); 721 Twitter.SetCredentials("Username", password); 722 723 StatusService service = Twitter.CreateStatusService(); 724 // or StatusService service = new StatusService("Username", password); 725 726 List<Status> tweets = service.GetUserTimeline("MichaelHerndon"); 727} 728 729</pre> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Amplify.aspx">Amplify</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/DataContractJsonSerializer.aspx">DataContractJsonSerializer</a>, <a rel='tag' href="http://www.amptools.net/labels/JSON.aspx">JSON</a>, <a rel='tag' href="http://www.amptools.net/labels/REST.aspx">REST</a>, <a rel='tag' href="http://www.amptools.net/labels/Twitter.aspx">Twitter</a>, <a rel='tag' href="http://www.amptools.net/labels/WCF.aspx">WCF</a></p> 730 </div> 731 <div class="blog-footer"> 732 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=3907268195622759157"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=3907268195622759157;><span style="text-transform:lowercase">3 Comments</span></a> 733 734 <a class="comment-link" href="http://www.amptools.net/2008/07/amplify-twittern-yet-another-c-twitter.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 735 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=3907268195622759157" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 736 737 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 738 </div> 739 740 741 742 <h2 class="blog-title"><a name="7486419527659460638"></a> 743 744 Pursuit of Rails like Active Record for C# 745 746 <span class="blog-byline"> 747 by: michael herndon, at: 6/12/2008 05:25:00 PM 748 </span> 749 750 </h2> 751 <div class="blog-content"> 752 <p>After trying <a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx" rel="tag">linq to sql</a>, <a href="http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx" rel="tag">the ado.net entity framework</a>, php's <a href="http://codeigniter.com/">code igniter</a> framework, php's <a href="http://www.cakephp.org/" rel="rel">cake framework</a>; I'm realizing how much of rails really depends on the inner workings of ruby itself to do what it is able to do.  I've looked and poked around <a href="http://www.cakephp.org/" rel="rel">Castle's Active Record</a> and it does some heavy lifting, but it still seems to deviate too much from rails's version of active record.  One of the key things of porting a concept, is to keep it as close as possible so that developers can rely more on the same convention without having to relearn the concept in a different domain specific language.  Plus, I cringe a little when it leans too much on using <a href="http://www.hibernate.org/343.html" rel="tag">NHibernate</a>. </p> <p>It goes back to the whole "Don't make me think principle", that developers often to have to keep in mind when developing for an end user.  At first, I was thinking about creating a port would be simpler using linq with either "linq to sql" or the currently released "ado.net entity framework". After investigating, it would take a ton of invested time to either write a code generator for visual studio that would changed the way the pocos (plain old c# objects) are generated in order in corporate the changes. Also not to mention that these frameworks heavily rely on a repository pattern, that would probably cause too much pain to change for just one developer.  </p> <p>Square one?  Well close enough. C# and ruby have different strengths and weaknesses. However with enough thought and using C#3.0, I think its completely possible to get something that closely resembles rails enough to give anyone who has worked with rails, something that would be familiar if they needed to work on a project in .Net.  </p> <p class="blogger-labels">Labels: <a rel='tag' href="http://www.amptools.net/labels/Active Record.aspx">Active Record</a>, <a rel='tag' href="http://www.amptools.net/labels/BHAG.aspx">BHAG</a>, <a rel='tag' href="http://www.amptools.net/labels/C#.aspx">C#</a>, <a rel='tag' href="http://www.amptools.net/labels/CSharp.aspx">CSharp</a>, <a rel='tag' href="http://www.amptools.net/labels/Linq To Sql.aspx">Linq To Sql</a>, <a rel='tag' href="http://www.amptools.net/labels/Rails.aspx">Rails</a></p> 753 </div> 754 <div class="blog-footer"> 755 <a class="comment-link" href="https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=7486419527659460638"location.href=https://www.blogger.com/comment.g?blogID=7043853799247804655&postID=7486419527659460638;><span style="text-transform:lowercase">0 Comments</span></a> 756 757 <a class="comment-link" href="http://www.amptools.net/2008/06/pursuit-of-rails-like-active-record-for.aspx#links"><span style="text-transform:lowercase">Links to this post</span></a> 758 <span class="item-action"><a href="http://www.blogger.com/email-post.g?blogID=7043853799247804655&postID=7486419527659460638" title="Email Post"><img class="icon-action" alt="" src="http://www.blogger.com:80/img/icon18_email.gif" height="13" width="18"/></a></span> 759 760 <script type="text/javascript" src="http://w.sharethis.com/widget/?tabs=web%2Cemail&charset=utf-8&services=reddit%2Cdigg%2Cfacebook%2Cmyspace%2Cdelicious%2Cstumbleupon%2Ctechnorati%2Cpropeller%2Cblinklist%2Cmixx%2Cnewsvine%2Cgoogle_bmarks%2Cyahoo_myweb%2Cwindows_live%2Cfurl&style=rotate&publisher=baa2824f-9291-46c0-87b4-6d5a72508a05&headerbg=%23dddddd&inactivebg=%231bb601&inactivefg=%2370eb00%09&linkfg=%231bb601"></script> 761 </div> 762 763 </div> 764 <div class="right"> 765 <h3> 766 Connect 767 </h3> 768 <ul> 769 <li> 770 <a href="http://www.twitter.com/michaelherndon"> 771 <img src="/content/images/twitter-badge.png" alt="Twitter badge" /> 772 </a> 773 </li> 774 <li> 775 <a href="http://www.facebook.com/profile.php?id=824905532"> 776 <img src="/content/images/facebook-badge.png" alt="Facebook badge" /> 777 </a> 778 </li> 779 <li> 780 <a href="skype:michaelherndon?add"> 781 <img src="http://download.skype.com/share/skypebuttons/buttons/add_green_transparent_118x23.png" alt="Add me to Skype" /> 782 </a> 783 </li> 784 </ul> 785 786 <h3> 787 <a href="http://feeds.feedburner.com/amptoolsnet" rel="alternate" type="application/rss+xml"> 788 Subscribe in a reader <img src="http://www.feedburner.com/fb/images/pub/feed-icon32x32.png" style="vertical-align:middle" alt="" /> 789 </a> 790 </h3> 791 <ul> 792 <li> 793 794 </li> 795 <li> 796 <a href="http://feeds.feedburner.com/amptoolsnet"> 797 <img src="http://feeds.feedburner.com/~fc/amptoolsnet?bg=990066&fg=CCCCCC&anim=0" alt="" /> 798 </a> 799 </li> 800 <li> 801 <a href="http://add.my.yahoo.com/rss?url=http://feeds.feedburner.com/amptoolsnet" title="amptools.net"> 802 <img src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif" alt="" /> 803 </a> 804 </li> 805 <li> 806 <a href="http://fusion.google.com/add?feedurl=http://feeds.feedburner.com/amptoolsnet"> 807 <img src="http://buttons.googlesyndication.com/fusion/add.gif" alt="Add to Google Reader or Homepage"/> 808 </a> 809 </li> 810 <li> 811 <a href="http://www.pageflakes.com/subscribe.aspx?url=http://feeds.feedburner.com/amptoolsnet" title="Add to Pageflakes"> 812 <img src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&fileName=ATP_blu_91x17.gif" alt="Add to Pageflakes"/> 813 </a> 814 </li> 815 <li> 816 <a href="http://www.bloglines.com/sub/http://feeds.feedburner.com/amptoolsnet" title="amptools.net" type="application/rss+xml"> 817 <img src="http://www.bloglines.com/images/sub_modern11.gif" alt="Subscribe in Bloglines" /> 818 </a> 819 </li> 820 <li> 821 <a href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http://feeds.feedburner.com/amptoolsnet" title="amptools.net"> 822 <img src="http://www.newsgator.com/images/ngsub1.gif" alt="Subscribe in NewsGator Online" /> 823 </a> 824 </li> 825 </ul> 826 <h3 class="sidebar-title"> 827 Previous Posts 828 </h3> 829 <ul id="recently"> 830 831 <li><a href="http://www.amptools.net/2008/11/simple-log-in-amplify.aspx">Simple Log in Amplify </a></li> 832 833 <li><a href="http://www.amptools.net/2008/10/gallio-and-mb-unit-release-v304.aspx">Gallio and Mb-Unit release v3.0.4</a></li> 834 835 <li><a href="http://www.amptools.net/2008/10/moving-amplify-to-git-hub.aspx">Moving Amplify To Git Hub...</a></li> 836 837 <li><a href="http://www.amptools.net/2008/08/getting-datadirectory-folder-in-c-sharp.aspx">Getting the |DataDirectory| folder in C sharp</a></li> 838 839 <li><a href="http://www.amptools.net/2008/08/ampliy-fusion-javascript-libraries.aspx">Amplify-Fusion, JavaScript libraries compatibility...</a></li> 840 841 <li><a href="http://www.amptools.net/2008/07/amplify-wcf-twitter-api-client-library.aspx">Amplify's WCF Twitter API Client Library v0.2</a></li> 842 843 <li><a href="http://www.amptools.net/2008/07/use-c-to-determine-where-and-what.aspx">Use C# to determine where and what version of java...</a></li> 844 845 <li><a href="http://www.amptools.net/2008/07/using-wcf-to-access-flickr-json-api.aspx">Using WCF to access the Flickr JSON API</a></li> 846 847 <li><a href="http://www.amptools.net/2008/07/sample-mixins-for-httprequestbase-to.aspx">Sample Mixins for HttpRequestBase to use with Asp....</a></li> 848 849 <li><a href="http://www.amptools.net/2008/07/amplify-twittern-yet-another-c-twitter.aspx">Amplify's TwitterN, Yet Another C# Twitter REST AP...</a></li> 850 851 </ul> 852 <h3 class="sidebar-title"> 853 Archives 854 </h3> 855 <ul class="archive-list"> 856 857 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_03_30_index.aspx">03.30.2008</a></li> 858 859 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_04_06_index.aspx">04.06.2008</a></li> 860 861 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_06_08_index.aspx">06.08.2008</a></li> 862 863 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_07_06_index.aspx">07.06.2008</a></li> 864 865 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_07_13_index.aspx">07.13.2008</a></li> 866 867 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_07_20_index.aspx">07.20.2008</a></li> 868 869 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_07_27_index.aspx">07.27.2008</a></li> 870 871 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_08_03_index.aspx">08.03.2008</a></li> 872 873 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_08_10_index.aspx">08.10.2008</a></li> 874 875 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_10_26_index.aspx">10.26.2008</a></li> 876 877 <li><a href="http://www.amptools.net/blogs/michaelherndon/archives/2008_11_02_index.aspx">11.02.2008</a></li> 878 879 </ul> 880 </div> 881 882</asp:Content>