Posts

Showing posts from January, 2009

I love Paul

1 Cor 6:12 "Everything is permissible for me" — but not everything is beneficial. "Everything is permissible for me" — but I will not be mastered by anything.

I'm an idiot

I worked on a crapload of small ASP.NET projects where I spent a lot of time on user management: add users, edit users, change roles, verify roles and so on. This includes tiny projects like a tiny website where the content of about 10 pages can be edited by the customer (mostly by adding news). They'll never have more than one person doing these edits, their primary business is totally unrelated to computers. Well, I was reading this article by Scott Hanselman and what do I see: Does it need an administrative console?, I ask. He says that'd be nice, but it wasn't spec'ed out. He figured this would be pretty low rent. The client even suggested (gasp) that they could just maintain a local XML file. How on Earth can I be so stupid? I always knew that ASP.NET had this feature... it just never crossed my mind to use it. Dammit.

Yes to mentoring, no to certification

Great article here . I hate the programmers dragging the certification bogey-man every time they have a problem with someone's code. Yeah, we really want to have the problems of the medical field. This article is a breath of fresh air.

Take that, ServiceLocator denigrators!

From Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler: The choice between Service Locator and Dependency Injection is less important than the principle of separating service configuration from the use of services within an application. Ha! :P

More on MVC

Follow-up to this . This is the structure I've settled on for the time being: View Controller Service Model Repository Data layer (eg, Linq to SQL) Data storage (eg, SQL database) The View, Controller and Service communicate through DTOs (aka ViewModels); the View and Controller never see the (domain) Models. I'm not 100% decided about the Service - Repository interface: should the Model objects be the same as the Data Layer objects? For purity reasons I'd say no - it's a bad idea to return Linq to Sql objects to the Service because it will cause problems when trying to switch to (say) Entity Framework. However, I haven't yet worked on a project big enough that the benefits of this separation outweigh the drawback of creating 3 different classes for the same entity (Linq Order, Model Order, DTO Order). I'll have to see what happens when I actually do work on a larger project (with this architecture I mean, I work on huge projects but not with this structure). Th...

TDD and discipline

In a comment on his article , Karl Seguin has this to say about the usefulness of TDD: My best suggestion was to unit test as you go, and most of these problems would have ironed themselves out. They never would have gotten the 100+ line controller actions under test, and would have had to address the problem upfront. Well... unfortunately, that only works for someone who truly believes in the value of TDD, figures out the "hint" - and then is disciplined enough to do the right thing. You know what my reaction is, in these cases? Screw the tests, I have code to write! Which, of course, is the wrong thing to do. I feel the need for a serenity prayer...

Nice methods in the ServiceLocator class

I just like the way these methods look. I'd take the ServiceLocator class to a job interview :) /// <summary>    /// This is used by the application when it needs an instance of T    /// </summary>    /// <param name="T">Type that the application needs an instance of</param>    /// <returns>An instance of T</returns>    public   static   object  GetInstanceOf(Type T)   {      lock  (containerLock)        if  (container.ContainsKey(T))          return  container[T]();         return  CreateInstance(T) ?? (OnTypeNotFound !=  null  ? OnTypeNotFound(T) :  null );...

Really weird C# code

My ServiceLocator (which has been further updated since my last post on it, so on the off chance that anybody wants the latest version, leave me a comment) can only register functions with no parameters - Func<T> . What happens if one wants to register a function with one or more parameters? As an example, let's say that I have many possible connection strings, and in some cases when I want an instance of DataContext I have to initialize it with one of those. Since my ServiceLocator doesn't accept functions with parameters, I cannot write var dc = ServiceLocator.GetInstanceOf<DataContext>(connectionString); Here's a way of transforming a function with parameters to one without: create a function that returns the original function. That is, given Func<T1, T> f; I need another function that will return f: Func<Func<T1, T>> g = () => (a) => f(a); So, in order to register my DataContext I am now going to use the fo...

Be careful with sample code

Found this code somewhere, it doesn't matter where: public   override   bool  ValidateUser( string  strName,  string  strPassword)   {        //This is the custom function you need to write. It can do anything you want.         //The code below is just one example.            // strName is really an email address in this implementation            bool  boolReturn =  false ;           // Here is your custom user object connecting to your custom membership database        MyUserProvider oUserProvider =  new ...

MVC explained

... to myself, as I'm trying to learn it :) This is how I'm organizing a project I'm currently working on: View - this is used to render the model as HTML, since this is an ASP.NET project. The View can contain view logic, like displaying negative numbers in red. ViewModel - this is not necessarily the domain model (database table), but a view-specific model. An Order view, for example, needs to display data from an Order, multiple OrderDetails, a Customer and possibly a Seller (and maybe more). Right now, I handle this case by making a composite class with several properties: public   class  OrderModel   {      public  Order Order {  get ;  set ; }      public  IEnumerable<OrderDetail> Details {  get ;  set ; }      public  Customer Customer {  get ;  set ; }      public  Address ...

ServiceLocator anti-pattern?

I was trying to reply to this article but for some reason I cannot leave a comment there... there's no error message, my comment is simply ignored. So I'm replying here, hopefully I'll be able at some point to at least reply with the address of this article. Ok... so if I understand this correctly, Nick's problems with the ServiceLocator pattern are: 1) Because it's global, it cannot be tested 2) Sometimes we want to return the same instance for all Resolve() calls, sometimes a thread- or HttpContext-specific instance, sometimes a new instance each time; can't do that with a dictionary (I'm ignoring the points in the "Problems with..." section because I can't understand any of them. "All of the robustness that is achieved by forcing components to publicly declare dependencies is lost." - why? "When dependencies are retrieved from a global container, the container does not know the identity of the requestor, and is forced to retu...

Returning a default value in case of errors

Ever wrote something like this? if  (a !=  null  && a.b !=  null  && a.b.c !=  null )     result = a.b.c.d;   else      result =  null ;   I hate it. Given that I'm processing some XML files whose schemas I cannot change, there's not much to be done but bite the bullet. This page gave me the idea for the following helper functions: public   static  T Eval<T, ExceptionClass>(Func<T> func, Func<ExceptionClass, T> onError)     where ExceptionClass: Exception   {      try      {        return  func();     }      catch  (ExceptionClass e)     {        return  onError(e)...

More on ServiceLocator - caching

I got an idea while watching this webcast with Rob Conery and Jeremy Miller - Jeremy was talking about StructureMap and how you can set caching with it. It took me a few hours but I managed to duplicate that functionality. Of course, it doesn't work when you call Discover() - that one will still be the regular un-cached call (I think Jeremy calls it PerInstance). This is an usage example: Bind<DataContext>    .To(() => new DBDataContext())    .CacheBy(InstanceScope.Singleton);  Bind<IProductRepository>    .To(() => new ProductRepository())    .CacheBy(InstanceScope.HttpContext);  Here are the helper classes in all their glory: using System;  using System.Collections.Generic;  using System.Threading;  using System.Web;    namespace Helper  {    // usage:   ...