Sponsors

The Lounge

Most Commented On

Current Bloggers

Partners

More signs of FubuMVC getting real

Posted by Jeremy D. Miller, Tuesday, February 09, 2010 (225 views)

Just launched last night:  http://guides.fubumvc.com/.  The main page has been around for a couple weeks now at http://fubumvc.com/.

It's not that much yet, but I think the existence of *any* documentation at this point is a good indication that we're serious about making the FubuMVC reboot take off.

If you're interested in getting involved, there's a TODO list that Chad & I are trying to keep up with ideas for extending FubuMVC at http://wiki.fubumvc.com/TODO and the developers list is at http://groups.google.com/group/fubumvc-devel.

Filed under:
Discuss (4)

VS 2010 RC1 available on MSDN

Posted by Patrick Smacchia, Tuesday, February 09, 2010 (268 views)

... and this RC1 will go public in 3 days. (if your are logged in MSDN, the link is: https://msdn.microsoft.com/en-us/subscriptions/securedownloads/default.aspx?pv=18%3a370)

I had access to the Release Candidate 1 limited community editions for a month, and I can say that hopefully, overall stability, performance and memory consumption have been greatly enhanced. As many, I was pretty angry with VS2010 beta2 performance and stability and it is good to see that MS engineers were able to address all these.

Also, a huge thanks to the Visual Studio Partners team that was pretty responsive and efficient during the last weeks. Thanks to their help, NDepend v3 beta3, I announced 12 days ago, works 100% with this VS 2010 RC1 version.We hope to have a NDepend v3 Release Candidate during next week.

Also, we prepared a screencast overview tour for this upcoming release integrated in Visual Studio 2010, 2008 and 2005. The fun part was that we used a synthesized English speaker for the speech in the screencast (it is Ryan US in the combo box). The reason is that in our team, we all have more or less strong French accent (I would say more for me, you can get a glimpse in this podcast with Scott Hanselman). (Tip: if you want to make your girlfriend or wife laugh, just type something sweet and make it say with the synthesized speaker Smile ).

 

 

Discuss (2)

Exploring MongoDB with F#

Posted by Matthew.Podwysocki, Tuesday, February 09, 2010 (803 views)

If you’ve been following me on Twitter, I’ve been digging a bit into MongoDB.  When I was involved with the planning of NoSQLEast this past year, I sat down and used it in anger and was quite pleased with the results.  Using it with a language which allows for quick prototyping such as F# has afforded me to get up and going on a project with very little effort.  At some point, I don’t want to be bothered with having to go into another tool, create a schema, decide what data types, run migrations and all the fun things that come along with traditional RDBMS solutions. I just want a quick answer with the data I have.  There was one issue of course that nagged me which was the ubiquitous use of strings for everything from databases, collections, and keys.  With a language such as F#, could we do any better than this approach?

From Dictionaries

Before we look at any potential solution, let’s first look at how we insert a document using the normal string approach with the C# MongoDB Driver.  Let’s take books for a potential book reviewing system as an example.  Let’s first insert a document into the collection.

open MongoDB.Driver

let mongo = new Mongo()
if not <| mongo.Connect() then
  failwith "Could not connect to MongoDB instance"
  
let books = mongo.["BookReviews"].["Books"]

// Insert a book
let book1 = new Document()
book1.["Title"] <- "Programming F#"
book1.["Authors"] <- ["Chris Smith"]
book1.["Publisher"] <- "O'Reilly"
book1["Rating"] <- 5.0

books.Insert(book1)

In the code above, I connected to the MongoDB instance I have running locally.  After that, I browse to the BookReviews database and then to the Books collection.  What’s interesting about that last piece is that if it doesn’t exist already, MongoDB will create it for me, so that saved me quite a bit from having to go into another tool, create a database, define columns, set indexes, etc.  After I get the Books collection, I then create a new Document with some keys and insert it into the collection.  Now, how about querying?  Let’s say I want to get all books by O’Reilly publishing.  How would I do it?

let oreillyQuery = new Document()
query.["Publisher"] <- "O'Reilly"

let oReillyBooks = books.Find(oReillyQuery)
printfn "O'Reilly books %d" Seq.length oReillyBooks.Documents

if not <| mongo.Disconnect() then
  failwith "Could not disconnect from MongoDB instance"

As you can see from the code above, we simply need to create a query document and set the appropriate keys.  Then we use the books collection to find it based upon our query.  Overall, it’s a great experience, but that’s an awful lot of string usage, more than my taste usually allows.  What can we do about it?

To Dynamic

As we covered in the previous post, F# has added support for both a dynamic get ( ? ) and set operator ( ?<-).  Note, that I said support and not actual implementation.  The actual implementation is up to you and your need.  There are a couple of solutions that we could explore on making our lives easier with this operator.  Ultimately, our goal is to look something like the following:

let mongo = new Mongo()
if not <| mongo.Connect() then
  failwith "Could not connect to MongoDB instance"

let books = mongo.["BookReviews"].["Books"]

let book = new Document()
book?Title <- "Real World Haskell"
book?Authors <- ["Bryan O'Sullivan"; "John Gorezen"; "Don Stewart"]
book?Publisher <- "O'Reilly"
book?Rating <- 4.6

books.Insert(book)

if not <| mongo.Disconnect() then
  failwith "Could not disconnect from MongoDB instance"

Or better yet, rid ourselves of the strings altogether such as BookReviews and Books.  One solution could be to use the incoming type in the ? operator to be an IDictionary as the MongoDB C# Driver Document class is based off an IDictionary. 

open System.Collections

let (?) (this : IDictionary) key =
  this.[key]

let (?<-) (this : IDictionary) key value =
  this.[key] <- value

This will allow for our calls to the document to be just as I wanted in the beginning.  But, that doesn’t cover how I could possibly cover the case for getting our database and our collection.  One common thread between the two of them is the indexed property of Item.  With that in hand, we could revisit the idea of using member restrictions to model this dynamic lookup of both gets and sets.  Let’s look at the code required for setting these member restrictions.

let inline (?) this key =
  ( ^a : (member get_Item : ^b -> ^c) (this,key))
 
let inline (?<-) this key value =
  ( ^a : (member set_Item : ^b * ^c -> ^d) (this,key,value))

This gives us not only the ability to deal with our Documents much as we had above, but also change our calls to get our database and collection, such as:

// Old
let books = mongo.["BookReviews"].["Books"]

// New
let books = mongo?BookReviews?Books

But, ultimately, as I pointed out in the last post, this has potential problems due to the nature of how F# treats the get_Item and set_Item properties.  For example, this solution does not work quite well with LINQ, such as the following will return an error.

let d = [dict [("dynamic", 123)];  dict [("dynamic", 456)]]

let allDynamics =
  query <@ seq { for m in d.AsQueryable() do
                   yield m?dynamic } @>
                   
val alllDynamics : seq<int> = Error: Specified method is not supported.                   

The previous example of using IDictionary/IDictionary<’Key,’Value>, however, does work in this scenario.  What about the DynamicObject approach?  As Scott Watermasysk described in his post on MongoDB and C# Dynamics it certainly is possible for us to take advantage of a DynamicObject with TryGetMember/TrySetMember defined.  But, how in F# could we take advantage of that?  I hope to cover that soon enough.

Conclusion

MongoDB has been a great source of inspiration for me lately as I look at Not Only SQL solutions.  Not having to worry about migrations, schemas, data types and the likes, I’ve been able to be quite productive in prototyping ideas, and getting answers quickly.  In addition, with a language such as F# where we can instantly get feedback through our REPL, it adds another dimension to trying out new solutions. 

With the flexibility of the F# language, we’re able to get some sort of syntactic sugar which allows us to make MongoDB look and feel much like we’re in LINQ to SQL without even the need for the dynamic bindings that are coming in .NET 4.0.

Filed under: , ,
Discuss (1)

Using and Abusing the F# Dynamic Lookup Operator

Posted by Matthew.Podwysocki, Friday, February 05, 2010 (917 views)

Lately, I’ve been playing with such things as MongoDB using F# to rapidly prototype ideas.  With that, I’ve tried to rid myself of magic strings by using the F# dynamic lookup operator.  I’ll cover exactly what I’m doing in the next post when using MongoDB, but in this post I’d like to explore a little of what you could do with a little noticed dynamic lookup operator in F#.

The Dynamic Lookup Operator

Much like C# 4.0 has the ability to do dynamic lookup, F# also has the same capability, although in a different capacity.  The language has support for a dynamic lookup get operator ( ? ) and set operator ( ?<- ), but note that I said support and not actual implementation.  The actual implementation is up to you and how you want to use it. 

The Get Operator

Let’s start off by implementing the get operator to get a public property (not super useful yet).

let (?) (this : 'Source) (prop : string) : 'Result =
  let p = this.GetType().GetProperty(prop)
  p.GetValue(this, null) :?> 'Result

We can write an example that verifies the behavior such as comparing a normal invocation and our “dynamic” invocation, as in this example of comparing getting the length of a string.

[<Fact>]
let ``Dynamic lookup should equal normal``() =
  areEqual "foo".Length "foo"?Length

But, we’re not limited to that.  For example, we could instead decide that we want to get a private member instead of a public one.  We could change up our example from above just slightly.

let (?) (this : 'Source) (prop : string) : 'Result =
  let flags = BindingFlags.GetProperty |||
              BindingFlags.NonPublic
  let p = this.GetType().GetProperty(prop, flags)
  p.GetValue(this, null) :?> 'Result

We can verify our behavior of this idea with a little example, for example invoking a private property in a custom class such as the following:

type PrivateProperty(propValue : string) =
  member private __.PropValue
    with get() = propValue
    
[<Fact>]
let ``Can invoke private property``() =
  let expected = "foo"
  let p = PrivateProperty(expected)
  
  let actual : string = p?PropValue
  
  areEqual expected actual

So, as you can see, this is quite useful so far, but we’ve only scratched the surface.  We’ve just dealt with properties so far, but what about methods?  The same applies here as well.  In this instance, let’s take a method that could have any number of arguments and invoke it just as if we would normally.

open Microsoft.FSharp.Reflection
open System.Reflection

let (?) (this : 'Source) (member' : string) (args : 'Args) : 'Result =
  let argArray =
    if box args = null then null
    elif FSharpType.IsTuple (args.GetType()) then
      FSharpValue.GetTupleFields args
    else [|args|]

  let flags = BindingFlags.GetProperty ||| BindingFlags.InvokeMethod
  this.GetType().InvokeMember(member', flags, null, this, argArray) :?> 'Result

What we needed to do here is take not only the member but the arguments as well.  If the arguments object is null (or unit), then we pass a null objet array, else if our type is a tuple, then we create an array from our tuple, and finally if it’s a single argument, then we make it into an array.  Finally we invoke our member with the flags to say it is either a property getter or a method and invoke with our arguments.  Let’s write an example of how to use this.

[<Fact>]
let ``Can invoke method with dynamic lookup``() =
  isTrue ("dynamic"?Length() > 0)
  isTrue ("dynamic"?EndsWith("ic"))
  areEqual "dyn" ("dynamic"?Substring(0,3))

Above are three tests which show no arguments, a single argument, and finally tupled arguments.  But what about setters?

The Set Operator

Just as we have the ( ? ) operator reserved for the get operator, we have the ( ?<- ) operator reserved for the set.  This allows us to be able to set any number of things with the same ease as the get.  For example, we could set a public property:

let (?<-) (this : 'Source) (property : string) (value : 'Value) =
  this.GetType().GetProperty(property).SetValue(this, value, null)

This simply gets the property and then sets the appropriate value.  And then we can write a test as an example of how it should work.

type MutablePropertyClass(value : string) =
  let mutable v = value
  
  member __.Value 
    with get() = v
    and  set(value) = v <- value
    
[<Fact>]    
let ``Dynamic setter should set property``() =    
  let m = MutablePropertyClass("foo")
  
  m?Value <- "dynamic"
  
  areEqual "dynamic" m.Value

In this example, we have a simple class with a property with a getter and setter and then we set our property using our special operator and then compare the values.  Once again, this is flexible enough where we could set private properties much as we retrieved them above.  Now, let’s put them together for a few quick examples.

The Dictionary Example

One idea that we could go with is instead of using string keys for dealing with key value pairs, we could use our dynamic getter and setter instead.  Nothing like a bit of syntactic sugar to brighten your day to lessen the noise.  Our goal for this is to go from:

let d = Dictionary<string,obj>()
d.["StaticKey"] <- "Meh"

To something like the following:

let d = Dictionary<string,obj>()
d?DynamicKey <- "Totally!"

How could we pull this one off?  Well, we could implement the dynamic lookup getter and setter to do nothing more than look in the dictionary as follows:

open System.Collections

let (?) (this : #IDictionary) key =
  this.[key]

let (?<-) (this : #IDictionary) key value =
  this.[key] <- value

Now we can verify our behavior with our test that we should have written first.

let ``Dictionary should get and set dynamically``() = 
  let d = Dictionary<string,obj>()
  
  d?DynamicKey <- "hello"
  
  areEqual d.["DynamicKey"] d?DynamicKey

A solution like this could work well for situations like MongoDB, which we’ll get into with our next post.  But, could go a step further and to say anything with the Item property could be ours for the taking.

The Item Indexer Property Example

In the .NET libraries, we have a few classes which expose an indexer property like an array, a Dictionary, and even a string.  It would be nice to have a way to both get and set this value through the use of our dynamic lookup operator, but how could we pull this off?  In some previous posts, I talked about generic restrictions in the F# language, and one in particular stands out, the member restriction operator.  This operators lets us constrain a given object parameter so that it must implement the following methods and properties.

Remember, our overall goal is to support calling this:

open System.Collections.Generic

let d = Dictionary<string,string>()
d?DynamicKey <- "Totally!"

type IndexedObject() = 
  let d = Dictionary<string,string>()

  member self.Item
    with get(key) =
      d.[key]
    and set key value =
      d.[key] <- value
      
let i = IndexedObject()
h?IndexedKey <- "IndexedValue"

So, what we have is both a Dictionary<TKey,TValue> and a custom indexed object.  Since they do not follow an inheritance chain which exposes an Item property, we cannot use the example from above with the IDictionary.  Instead, we’ll use member restrictions for both the method get_Item and set_Item.

let inline (?) this key =
  ( ^a : (member get_Item : ^b -> ^c) (this,key))
 
let inline (?<-) this key value =
  ( ^a : (member set_Item : ^b * ^c -> ^d) (this,key,value))

What you see is that we’re calling both the get_Item and set_Item properties, which are the raw method names for the Item property.  Now we’re able to verify our test using our IndexedObject class from above:

let ``Can use dynamic indexed getter and setter``() =
  let i = IndexedObject()
  
  i?SomeKey <- "Some value"
  
  areEqual i.["SomeKey"] i?SomeKey

A big word of caution when using this approach is that you’ll get a nice warning from the F# compiler that doing this may cause unverified code as F# treats the Item property specially.  For example, all value types must be boxed before putting them into the collection.

let h = Hashtable()
h?MyKey <- 3 // Don't do this

h?MyKey <- box 3 // Do this

Very powerful way of doing things but also you must be careful with this approach if you use it at all.

Conclusion

So, as you can see, F#, just like C# has the facilities for dynamic lookup, although in F# you are left to implement it yourself in any which way you like.  One great thing about these operator is that it doesn’t require .NET 4.0 to implement and use them.  But with any power comes of course some responsibility for it, so use it wisely.

Filed under:
Discuss (2)

Scoop: Reflector v6 pro RTM to be released by the 15th of this month

Posted by Patrick Smacchia, Friday, February 05, 2010 (983 views)

This is really exciting time these days. Most of .NET tooling vendors are about to provide a major upgrade of their products within the next weeks. And Reflector is part of the lot! A brand new version, Reflector v6, is about to be go live RTM on Monday 15th of February 2010. This will be the first time the company Red-Gate will update the product since it has been acquired from its original creator, Lutz Roeder, in August 2008.

There are 90% of chances you are using Reflector daily so don't be afraid: current Reflector features will continue to be provided in a free version of the tool. The Red-Gate strategy is to append new innovative features to the tool, and only these features will require a professional purchased version. The flagships features of Reflector v6 is the ability to debug source code decompiled from IL code, in the Visual Studio debugger. This is certainly a killer one: we all need at a point to have a better understanding of what's happening at runtime in Framework used by our code.

Having used Reflector v6 beta, I can say that plenty of cool featurettes have been also been added, including a bridge between Reflector and Visual Studio (ok this one is already provided more or less by several tools, including TestDriven.NET and NDepend)

 

Another cool thing is that the upcoming NDepend v3 is working hand-in-hand with Reflector v6 (as a Reflector addin). And as NDepend v3 is also a Visual Studio 2010 / 2008 /2005 addin, all NDepend features constitute more glue between Reflector v6 and Visual Studio, including:

  • from Reflector to Visual Studio
    • Generating dependency graph and dependency matrix
    • Generating CQL queries
    • Opening Source files definition
  • from Visual Studio to Reflecor
    • Opening a code element (assembly, namespace, type, method, field) in the Reflector class browser
    • Decompiling a code element in a source file in any language supported by Reflector (IL, C#, VB.NET, MC++I, Oxygen, Delphi)
    • Decompiling an older and a newer version of a code element in 2 text files, and comparing the 2 text files with your preferred diff tool.

 

Discuss (4)

StructureMap 2.6 (and 2.5.4) is Released!

Posted by Jeremy D. Miller, Thursday, February 04, 2010 (2,400 views)

Time flies when you’re having fun.  It’s been almost a year since I’ve made an official StructureMap release, so I guess it’s about time.  This morning I uploaded the binaries for the 2.6 release.  This release just adds some bug fixes and a couple minor additions to the 2.5.4 release that I made in December but didn’t really publicize.  The release notes below are long, but that’s because they represent almost a year’s worth of development.  As I said yesterday, StructureMap is most likely moving to GitHub with the documentation going as well.  After a massive effort to write documentation early last year, huge chunks of it is already obsolete and there’s been a lot of addition since.  I’m hoping that the move to the Wiki will make it easier to keep the docs up.  In the meantime, I’ll try to blog a bit about the newer pieces starting tomorrow.

A tiny bit of history.  This is the 11th StructureMap release since it debuted way back in June of 2004.  Almost nothing is the same.  We use it differently, the expectations are different, and very, very little of the original code survives today.  At QCon San Francisco in 2008 I talked about what I’d learned from evolving this codebase over so many years and changes.

This release includes a lot of patches from the community, and I’d like to thank all of you for that – especially Frank Quednau and Andreas Ohlund for taking on some nastier things.  Josh and Kevin Miller do yeoman duty answering StackOverflow questions (so I don’t have to). 

 

What’s Changed?

  • New terse, “jQuery-esque” syntax for the Registry DSL.  Let’s just write off “ForRequestedType<IFoo>().TheDefault.Is.OfConcreteType<Foo>()” as a well meant experiment, shall we?  It’s still in the codebase, but it’s marked as [Obsolete].  Nobody liked it and I thought it was annoying in real life usage.  Now, just do:  For<IFoo>().Use<Foo>();  My whole goal was to reduce friction.  Needs a big blog post
  • Changed the Registry DSL to make inline dependency configuration be more consistent.  Definitely a blog post.
  • The “CreateProfile” syntax has gotten a lot of complaints for being inconsistent with the rest of the Registry DSL.  I basically rewrote it to now be consistent with the “For<>().Use()” syntax in the main Registry DSL.  Blog post coming soon….
  • Nested Container feature for short lived transactional requests.  I built this for Dovetail usage, but I think it’s my preferred way to manage object scoping in certain circumstances.  I mentioned it just a little bit in my NHibernate w/ StructureMap post a couple weeks back.  Blog post coming soon…
  • The “Model” feature was completely redone.  There’s a lot more power, and you can use it to pull services out of the Container and completely remove services from the Container as well.  Sigh.  Needs a blog post.
  • Convention based type registration got a lot of work.  People are pushing this feature very hard and it had to grow.  You can now use the Registry DSL to write conventions.  This was improved farther in the latest code drop.  Yeah, blog post coming…
  • Better support for registering services by Type objects for cases when you don’t necessarily know the Type upfront.  Big request from several framework authors like Caliburn.
  • A helluva lot of new features to make working with open generic types easier.  Jimmy Bogard blogged about some of it here.  I’d like to show how StructureMap’s new features would make writing something like Davy Brion’s Agatha framework a snap.  I use this stuff extensively inside of StoryTeller.
  • Added the lazy Func<T> feature from Autofac.  A really great (and cheap) way to support lazily initialized components.  Blog post coming.
  • Completely ditched all Reflection.Emit code.  StructureMap now strictly uses dynamically constructed Expression’s that are pre-compiled into cached Func’s.  I don’t know if that really makes much difference to users, but it makes StructureMap much, much easier to extend.  The container does spin up faster with this mechanism.  Makes me happy.
  • Supports IList<T> and List<T> arguments.  It works just like Arrays.  That’s been a while coming.
  • You can set the lifecycle from <AddInstance> if you happen to still use Xml configuration. 
  • The “Lifecycle” code was completely reworked to eliminate shared code
  • Container.Dispose() was introduced.  I’ve put a lot of effort into making StructureMap clean up after itself.  Definitely a blog post coming.
  • ObjectFactory.Container.  Slowly, but surely, I’d like to wean people away from using ObjectFactory too much in favor of scoped Container objects.  I will NOT be further extending the ObjectFactory static methods to synchronize it with IContainer.  Instead, I’m just exposing the ObjectFactory.Container property.
  • New abilities for IContext like BuildUp() (thanks to Kyle Malloy), getting all instances, and TryGetInstance
  • TryGetInstance() from Josh
  • Killed StructureMapConfiguration.  Good riddance.
  • “Forwarding” requests for IFoo to whatever IBar is
Filed under:
Discuss (20)

Business Primitives (2/2)

Posted by drusellers, Thursday, February 04, 2010 (1,291 views)

Ok, so now that we have talked about the Business Primitive concept lets go through some of the actual examples. Let's take an example of a 'Loan' class.

public class Loan
{
    public int Id { get; set; }
    public int InterestRate { get; set; }
    public DateTime TradedOn { get; set; }
    public DateTime SettledOn { get; set; }
    public decimal Principal { get; set; } 
}

After some small tweaks.

public class Loan
{
    public int Id { get; set; }
    public Rate Interest { get; set; }
    public DateTime TradedOn { get; set; }
    public DateTime SettledOn { get; set; }
    public Money Principal { get; set; }
}

Already the code feels more robust to me. The dates aren't that interesting to the business other than they are dates so they haven't yet been uplifted into 'business primitives' but Interest has been converted to 'Rate', which immediately helps with math and providing meaningful math like methods, as well as Principal which is now 'Money' which also helps with math and the more pernicious rounding issues.

So how was 'Rate' implemented? What does it look like?

[DebuggerDisplay("{_rate}%")]
public class Rate
{
    int _rate;
    private Rate() { }
    
    //factory methods
    public static Rate FromWholePercent(int rate) { new Rate(){_rate = rate};}

    //equality overrides here
    //operator overrides here
} 

First, we have the 'DebuggerDisplay' attribute which is my new best friend, it allows you to customize how the debugger displays your object in the debug view, very helpful. I have wrapped the previous rate value in a very simple fashion, and now we have a nicely centralized place to put math based functions (myRate = baseRate+riskRate). I have also added a factory method that help explain how this Rate object is being made. From whole percents such as 78% or 22%. Because we have hidden the way we actually store the value, we could also add support for 22.2% by adding a new factory method and changing the internal storage with out changing any other part of the code base. Very cool.

Ok, so what about saving these value objects and now I need to bind them to the UI how do I get at that hidden variable? I have taken quite a few paths when trying to implement this and the way that I do things now is a combination interface + base class. If you are anything like me you are thinking 'base class, yuck' and well I still do but this is the best way that I have come up with and I am open for suggestions. :)

So my 'business primitives' inherit from an abstract class called 'Primitive<T>' this class helps to streamline the creation of my business primitives. It also EXPLICITLY implements an interface called ValueObject<T> that exposes the underlying value, that can be used by UI controls and persistance frameworks with out mucking up my public API. I love that I don't see 'SetValue' and 'GetValue' unless I want to (yes, this could have been a property, not sure why I choose this). Here is the interface:

public interface ValueObject<T>
{
    void SetValue(T input);
    T GetValue();
}

and the base class

[DebuggerDisploy("{_primitiveValue}")]
public class Primitive<T> :
    ValueObject<T>
{
    T _primitiveValue;

    public Primitive()
    {
    }

    public Primitive(V primitiveValue)
    {
        _primitiveValue = primitiveValue;
    }

    void ValueObject<T>.SetValue(T input)
    {
       _primitiveValue = input;
    }

    T ValueObject.GetValue()
    {
        return _primitiveValue;
    }
        
    //equality stuff
}

I really wanted to do some tricky generics to try and implement the operator overloads in the base class as well, but the compiler wasn't to happy about that so those still have to be implemented in the 'Rate' class. Now my 'Rate' object looks like this:

public class Rate :
    Primitive<int>
{
    private Rate() { }
    private Rate(int value) : base(value){}

    //factory methods
    public static Rate FromWholePercent(int rate) { new Rate(rate);}

    //operator overloads should be implemented here

    public bool Equals(Rate other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return base.Equals(other);
    }
} 

For saving these buggers? Well, using NHibernate we can persist this as an 'int' using an IUserType, which makes things very simple and still manages to keep NH out of our domain.
Some links on implementing IUserTypes

Otherwise, with the interface you now have the means to get access to the value, so customize for your needs!

Now that we have addressed the saving aspect, what's a good way to present these 'business primitives'? Because

inputLoanPrincipal.Text = loan.Principal.ToUiString();
sucks. I would suggest some extension methods on your UI controls that take Primitive<T> as the type and can then cast to the ValueObject and get access to the value. Or extending the UI binding much in the way FubuMVC has, seems like a really solid way to approach things too.

I hope this helps :)

-d

Filed under:
Discuss (10)

Getting StructureMap off SourceForge, Thoughts?

Posted by Jeremy D. Miller, Wednesday, February 03, 2010 (1,071 views)

The original discussion for this topic is here:  http://groups.google.com/group/structuremap-users/browse_thread/thread/6d579f4e9b508c66

 

All,

I've never liked SourceForge and it's a PITA for me to use even though it's gotten better over the years.  I'd like
to move StructureMap off SourceForge and more importantly, get a real
Wiki site up so that we have at least a fighting chance of keeping the
documentation up to date.  On the other hand, I get a significant
number of patches from you guys (thanks for that) and I'd also like a
better way of handling those submissions -- and making it easier for
*you* to get involved.

Right now, Josh and I are thinking about moving StructureMap to GitHub
(you knew that was coming) and trying to use the Wiki support on
Github for now.  Granted, Git is weird as hell for those of us used to
SVN, but GitHub has some huge advantages for OSS community
development.  I'd *love* to start managing StructureMap patches
through GitHub "pull" requests (or whatever the correct lingo is).

Any thoughts?  Volunteers? ;)

Jeremy

Filed under:
Discuss (22)

An introduction to iptables

Posted by karl, Wednesday, February 03, 2010 (1,710 views)

iptables is a linux application that allows you to configure the built-in linux firewall. There are abstraction layers built on top of it, including nice GUIs, but I recently had some very basic rules I wanted to implement, and figured I'd learn how to do it directly in iptables. It turned out to be easy to configure, and I thought I'd give a very basic introduction.

First though, I relied on the ubuntu documentation to get up and running (https://help.ubuntu.com/community/IptablesHowTo). I'll pretty much just regurgitate what's in there - I've said it before, stop believing that linux documentation is written only for people who already know linux. Also, depending on your setup, most of these commands might require elevation (sudo).

By default, iptables defines three rule chains: INPUT, FORWARD and OUTPUT. We'll only concern ourselves with INPUT - namely the chain used for incoming packets directed at this particular machine. At any point, you can list the rules by entering iptables -L. If listing the rules turns out to be really slow, try using iptables -L -n. The -n option means that the display will output IP addresses and ports in numeric format, without trying to do a DNS lookup. If the -n option makes it fast, then you're system likely has incorrect DNS settings (you can check out http://www.cyberciti.biz/tips/linux-how-to-setup-as-dns-client.html for help with that).

In my particular case, the server is has two network interfaces - a public facing one (on eth0) and a private one (on eth1). For my purposes, I want to remotely (eth0) access SSH from my static IP, and locally (eth1) access postgresql on port 5432.

To accomplish this we simply append two rules to the INPUT chain:

iptables -A INPUT -p tcp --dport ssh -s 205.38.19.199 -i eth0 -j ACCEPT
iptables -A INPUT -p tcp --dport 5432 -i eth1 -j ACCEPT

The first rule appends itself to the INPUT chain. Its limited to the TCP protocol targeting the SSH port (22) with a source originating from 205.38.19.199 on the eth0 network interface. It jumps to an ACCEPT status (all other processing stops). The next rule is similar, except it allows any source so long as they are connected to eth0 and targeting port 5432 (over tcp).

We can now add a third rule to block all other access:

iptables -A INPUT -j DROP

if incoming traffic doesn't mean the first two criteria, we'll hit this third rule and the firewall will reject the connection.

We'll run into 1 issue with our above configuration though - we've blocked access to the loopback interface (127.0.0.1). We need to add a special rule to allow loopback connections (since a lot of programs rely on it). However, we can't simply append it as it'll never be reached. Instead of using -a to append, we'll use -i to insert:

iptables -I INPUT 1 -i lo -j ACCEPT

Here we are inserting our rule in the 1st position, and accepting all connections made on the special lo (loopback) interface.

A really neat thing about iptables is that they aren't persisted by default. So, if you happen to mess up and cut yourself off from your server, a simple reboot will reset everything (hopefully you have access to do a remote reboot from a web interface, or maybe you can just walk up to the machine and reboot it).

At some point though, you'll want to make sure your rules are persisted. Achieving this is a two step process. First, you save your rules to a file by using the iptables-save and redirecting STDOUT to a file:

iptables-save > /etc/iptables.rules

Second, and this depends on which distro you have but on debian/ubuntu, you make sure your rules are loaded on startup. Simply edit /etc/network/interfaces, find your interface, and add:

pre-up iptables-restore < /etc/iptables.rules 

to the list, so that it looks something like:

auto eth0
iface eth0 inet static
address xxx
netmask yyy
gateway ddd
pre-up iptables-restore < /etc/iptables.rules

That's it!

Discuss (4)

Life outside .NET, or “How to check out your neighbours”

Posted by Kyle Baley, Tuesday, February 02, 2010 (2,349 views)

The hillbilly be all Java’d up these days. For coming on three weeks, I’ve been the lone developer on a project based on Google Web Toolkit. It’s a web framework (naturally) that allows developers to build applications in Java and compiles it down to JavaScript, CSS, and HTML. Scoff all you want, if it were any other company behind it, I’d probably be right there with you.

We considered quite a few technologies before landing on this one. We went through Ruby, Sharp Architecture, Open Rasta, Moo Tools, and probably several others. I can defend ending up Google Web Toolkit privately if you want but putting the thought process up in a public forum is going to lead to comments that I’m too tired to moderate these days. And yes, I’ve heard of Script #, too.

Coming at this from a .NET developer’s standpoint has been interesting. It’s surprising how much we take for granted in our IDE, for example. I’m still meandering my way through the keyboard shortcuts in Eclipse (after a brief fling with IntelliJ IDEA). One thing I’d really like is a keyboard shortcut for the GWT Compile button, which currently is available only via a toolbar button or a context menu, as far as I can tell. Was happy to find a VIM plugin for it too that works as advertised.

Not sure if this applies to Java in general but within the confines of the Google Web Toolkit, the ecosystem is freakin’ phenomenal. The documentation page alone encourages unit testing and the use of an MVP architecture. Once you start reading about it, you can’t help but stumble on a number of other projects:

  • gwt-presenter: A passive view implementation for GWT
  • gwt-dispatch: A command pattern implementation for GWT
  • Guice: Google’s dependency injection framework
  • Gin: A dependency injection framework for the client part of GWT

The shocking thing from a .NET perspective is that these concepts are just sort of assumed. There’s little debate on whether dependency injection is necessary or whether passive view is overkill. Someone watched a presentation from Google IO last year, whipped up a command pattern project based on it, and lo! the people said it was good. Between support for Hibernate and the App Engine data store, I think people would look at you bug-eyed if you even suggested writing your own data access layer.

The downside to all this as that the tooling seems to be several steps behind what I’m used to in the Microsoft world. It’s still too early to make a fair comparison but even after digging a little deeper into Eclipse, I can’t imagine being quite as productive as I currently am in Visual Studio. Yes, there’s also IntelliJ but our anecdotal evidence suggests that neither Java IDE is seen as a de facto standard. For the moment, I’m sticking with Eclipse simply because all the documentation refers to it and the GWT and App Engine plug-ins for it work out of the box.

Couple of final shout-outs to two blogs that have been invaluable during the learning curve phase. First is Hive Development (currently featuring two posts on how to unit test MVP applications in GWT). Second is TurboManage, whose sample code is more detailed than many apps I’ve written.

Anyway, it’s been an interesting couple of weeks.

Kyle the Decaffeinated

Filed under: ,
Discuss (22)

FubuMVC Learns to Speak Spark

Posted by Jeremy D. Miller, Tuesday, February 02, 2010 (650 views)

From Robert the Grey, FubuMVC learns to speak Spark

I've done the nearly solo OSS thing a couple times to mixed results.  I'm painfully aware that good OSS projects have a deeper community of contributors than just one guy, and that's why I'm so thrilled to see this addition come into the nascent FubuMVC reboot from outside the Dovetail office.

Filed under:
Discuss (3)

A Kick in the Monads – Writer Edition

Posted by Matthew.Podwysocki, Monday, February 01, 2010 (1,004 views)

In the past couple of Monads posts, we’ve talked briefly about the State and Reader Monads and their potential uses and misuses.  Before this series completes, I have a few more to cover including the Writer, Continuation and eventually Observable monad.  Today, we’ll get started looking at the Writer Monad and what it can do for us.

What’s the Motivation?

Before we dive deep into what the Writer Monad is, let’s go deeper into the motivation of why we might consider this approach.  Like proper developers should when approaching a new concept, we should ask, “What problem are we trying to solve?  What’s the motivation here?” else we end up with an over-applied solution to our problem.  In this case, let’s take the simple example of logging or tracing in our application.  Typically in logging scenarios, we could have the dreaded singleton logger.

let doSomething() =
  Logger.Instance.Log("Beginning doing something")
  
  // Doing something
  
  Logger.Instance.Log("End doing something")

Or perhaps, we could have an injected ILogger instance handed to us via a constructor for the purposes of logging.

type ILogger =
  abstract member Log : message : string -> unit

type DreadedManager(logger : ILogger) =

  member __.DoSomething() =
    logger.Log ("Start doing something")
    
    // Do something

    logger.Log("End doing something")

Or even in other scenarios, we might imagine putting in some AOP behavior for the purposes of logging, but that may of course not be fined grained enough what we need.  Instead of doing this, how about generating some output “on the side” in a more functional manner.  What if we could instead write something like the following where I add two numbers (simplistic example I know) and then run the computation?

let addNumbers x y = writer {
  do! logMsg (sprintf "Adding %d and %d" x y)
  return x + y };;
  
> val addNumbers : int -> int -> Writer<string list,int>

> addNumbers 3 4 |> runWriter;;
val it : int * string list = (7, ["Adding 3 and 4"])

What we’re seeing is that in my addNumbers function, I take two integer arguments and then log a message and finally return the computed value.  What’s more interesting is the fact that we’re logging something physically alters the signature of our method to indicate such a thing is happening.  When we compute our function, we not only get the result of 7 that we’re expecting, but also our transaction log as well.  Then we can decide what we want to do with the log, for example persist it somewhere, clean it up, etc.  So, how can we do this exactly?

Defining the Writer

So, now that we covered the motivations around what it is and why we might use it, let’s look at how we might implement it.  In order to maintain both the transaction log and the return value of our method, we’ll need to create a container to hold these values.  In this case, we have the Writer<’W,’T> where the ‘W is the writer, which in our case above was a simple string list, and the ‘T is the result of our method.  We have a constructing function of our Writer which takes a function with no parameters and returns a tuple of our result and the log.

type Writer<'W,'T> = Writer of (unit -> 'T * 'W)

In addition, we’ll need a way to run our Writer so that we can return our tuple of our value and the log.  Let’s create a function called runWriter which computes our Writer.

let runWriter<'W,'T> (Writer w) : ('T * 'W) = w()

Before we get started on the Monad part, there is another piece we need to understand, and that’s the Monoid.

Don’t Avoid the Monoid

Before everyone panics as I’ve brought up a work that sounds like Monad, just rest easy.  In fact, it’s much easier to understand than the dreaded M word.  A Monoid is an algebraic data structure with a simple associative binary operation and an identity element.  Just to bring that into real-world speak, we could have a Monoid for natural numbers with an identity element of 0 and the associative binary operator of addition, or in the case of lists, we could have the identity element of an empty list and an associative binary operator of append.  In Haskell, such a thing is implemented through a type class, but since in F#, we don’t have this, let’s instead create a simple interface to encompass the same behavior.

type IMonoid<'T> =
  abstract member mempty  : unit -> 'T
  abstract member mappend : 'T * 'T -> 'T

In this instance, we have two methods we care about, defining our identity (mempty) and our binary operator (mappend).  For example, we could implement a Monoid for a simple F# list such as the following:

type ListMonoid<'T>() =
  interface IMonoid<'T list> with
    member this.mempty() = []
    member this.mappend(a, b) = a @ b

This instance in particular will come in handy when we’re talking about a simple logging solution.  Our mempty simply returns an empty list of our ‘T objects and our mappend appends the first list to the next.  Now, what we need is some sort of registration process for our IMonoid instances so that we could pick one up based upon the incoming type.  We could use something like a Common Service Locator to do this and it could be idea for a testing situation, but for now, lets just hand roll a global associations which maps an instance of our IMonoid to our proper type. 

type MonoidAssociations private() = 
  
  static let associations = new Dictionary<Type, obj>()
  
  static member Add<'T>(monoid : IMonoid<'T>) = 
    associations.Add(typeof<'T>, monoid)
  
  static member Get<'T>() = 
    match associations.TryGetValue(typeof<'T>) with 
    | true, assoc -> assoc :?> IMonoid<'T>
    | false, _    -> 
        failwithf "No IMonoid defined for %O" <| typeof<'T>

Once we have this defined, we could add instances to this associations class such as a string list implementation:

MonoidAssociations.Add(new ListMonoid<string>())

And now we can use the associations class to call instances of our IMonoid for our functions of mempty and mappend.

let mempty<'T> = MonoidAssociations.Get<'T>().mempty
let mappend<'T> a b = MonoidAssociations.Get<'T>().mappend(a, b)

After that little diversion, we’re now able to get back to the point of the post, the Writer itself.  But outside of here, that’s probably the last time you’ll probably use the word Monoid.  But, I’m sure now you could impress your friends with the use of said word.

Defining the Builder

As you may remember from the previous post, the monad must support three basic rules.  First, a type construction, for each underlying type, we must be able to get the corresponding monadic type.  Second, we must have a function that maps an underlying value to a value in the corresponding monadic type, which is called the return function.  Third, we must have a binding operation where the first argument is a value in a monadic type, its second argument is a function that maps from the underlying type of the first argument to another monadic type, and its result is in that other monadic type.

Let’s first tackle the return function.  From our previous creating a Builder posts, we should remember that the Return should have the following signature where we take a value of T and then return it’s Monadic type.

type Builder() =
  member Return : 'T -> Monad<'T>

Our implementation should take a value of a and construct a Writer with a function with no arguments and return a tuple of our value and an empty Monoid instance.

type WriterBuilder() =

  member this.Return<'W,'T>(a : 'T) : Writer<'W,'T> = 
    Writer(fun () -> a, mempty())

Next, we need to define the bind operation.  The point of this method is so that we can bind two monadic types together such as two let! or do! statements.  As you might recall, this method takes a Monadic type of ‘T and a function that takes a ‘T and returns a Monadic type of ‘U, and the return type of our bind should be the Monadic type of ‘U.

type Builder() =
  member Bind : computation : Monad<'T> *  
                binder : ('T -> Monad<'U>) -> Monad<'U>

Our implementation should look like the following which creates a Writer with a constructed function which takes no parameters and then calls runWriter on our first Writer m which returns a tuple of our result and a log.  We then execute the binder function with our result a which then gives us our second result and a log.  Finally, we return a tuple of our second result with our two logs appended to each other.

type WriterBuilder() =

  member this.Bind<'W,'T,'U>(
    computation: Writer<'W,'T>, 
    binder : 'T -> Writer<'W,'U>)  : Writer<'W,'U> =
    Writer(fun () ->
      let (res1, log1)  = runWriter computation
      let (res2, log2) = runWriter (binder res1)
      in  (res2, mappend<'W> log1 log2))

You can find the rest of the methods in order to create a fully functioned builder as a Gist on my GitHub.  Now let’s talk about some helper methods.  The first, and most useful method is the tell which adds an entry to our log.  This function takes a log entry and creates a Writer with a function that takes no arguments and returns a tuple of unit (void for some folks) and our log entry.

let tell logEntry = Writer(fun () -> (), logEntry)

Next up is the listen function.  This allows us to listen to our log output that is being generated by our writer.  This function takes a Writer and executes it while returning a tuple of our result and a log, as well as a log.

let listen writer = 
  Writer(fun () -> let (result, log) = runWriter writer 
                   in ((result, log), log))

The last function we’ll cover is the censor function.  This function returns a new Writer whose result is the same, but the alters the log based upon what is supplied as a parameter

let pass   m = 
  Writer(fun () -> let ((a, f), w) = runWriter m in (a, f w))
  
let censor censoredValue writer = 
  writer { let! result = writer
           return (result, censoredValue)
         } |> pass

Doing Something Useful With It

Ok, our helpers are now defined, so let’s go back and figure out how we’re going to log messages.  If you remember from above, we have the tell function which does exactly that.  Let’s implement that to take a message and call the tell function with our message wrapped in a list.

let logMsg (message : string) = tell [message]

Now we can try it out in such a function which does some file processing for us with some logging along the way.

let processFiles files = writer {
  try

    do! logMsg "Begin processing files"
    for file in files do
      do! logMsg (sprintf "Processing %s" file) 
      processFile file

    do! logMsg "End processing files" 

  with e -> 
    do! logMsg (sprintf "An exception occurred %s" (e.ToString())) }

At the end of this method, it should return to us a tuple of unit and our log entries that happened along the way such as this:

> processFiles files |> runWriter;;
val it : unit * string list =
  (null,
   ["Begin processing files"; "Processing C:\Test1.txt";
    "Processing C:\Test2.txt"; "End processing files"])

This of course is a pretty contrived and simple example, yet pretty interesting nonetheless.  But, in an impure world that we live in with such languages as F#, C#, etc, how practical is it?  That’s another matter altogether and good arguments on both sides.  Using a writer implies some sort of change to your system to allow for logging, whereas in a more impure environment, logging could take place everywhere.  So, when dealing with an impure world already, just go with what you know.

Conclusion

Once again, by looking at Monads, we can discover what abstractions can be accomplished with them, but just as well, what they are not about.  Certainly, functional languages don’t need them, but they certainly can be quite useful.  When we find repeated behavior, such as logging, this abstraction can be quite powerful.  Practically though in languages such as F#, they can be useful, but other patterns and abstractions can as well.  Find the right abstraction and use it.

Discuss (0)

Exporting dynamically changing configuration values

Posted by Glenn Block, Sunday, January 31, 2010 (1,384 views)

In my last post I discussed how to export configuration. A follow up question in the comments was “What if the values change?” Meaning the values that are exported using the approach I illustrated are static. In the real world however values often can change based on some user setting etc. A variant of the approach however allows the values to not be static. Instead of exporting a value, export a Func which returns the value. MEF offers nice support for this through method exports. For example to allow the “recently used file” config item to change over time, we can modify the Exporter to export that value as a method rather than a property.

public class RecentlyUsedTrackerConfiguration
{
  private IConfigurationProvider _provider;
  [ImportingConstructor]
  public RecentlyUsedTrackerConfiguration(IConfigurationProvider provider)
  {
     _provider = provider;
     MaxItems = provider.GetValue<string>("recentlyUsedTracker.maxItems");
  }
  [Export("RecentlyUsedTracker.File")]
  public string GetFile() {
    return _provider.GetValue<string>("recentlyUsedTracker.maxItems");
  }
  [Export("RecentlyUsedTracker.MaxItems")]
  public int MaxItems {get;private set;}
}

Instead of exporting a property, we are now exporting  the GetFile method. Method exports are imported as delegates, thus RecentlyUsedTracker now looks like this.

[Export]
public class RecentlyUsedTracker {
  [Import("RecentlyUsedTracker.File")]
  public Func<string> File {get;set;}
  [Import("RecnetlyUsedTracker.MaxItems")]
  public int MaxItems {get;set;}
}

Notice above we are importing a Func<string> for the File item rather than string. This gives us the hook to dynamically change File each time it is accessed. You could even go further an parameterized File if you wanted to pass in context to determine which File is returned.

It’s still easy to test

With this approach RecentlyUsedTracker is still easy to test. With lambda syntax it is pretty painless to pass in test values when the class is under test.

Filed under:
Discuss (2)

From Hyper-V back (?) to Virtual PC

Posted by pvanooijen, Sunday, January 31, 2010 (1,365 views)

For over a year I have been using Server 2008, 64 bits, as OS for my laptop. The main reason for this platform was Hyper-V. Almost every other project I’ve been working on needs another virtual server.  And each location I am working has a different network. With Hyper-V both switching servers and switching networks works fast and good. The downside of using Hyper –V is that it knocks out all possibilities of hibernating or putting my laptop to sleep. Server 2008 R2 boots a lot faster, but still. Another downside is that to use Hyper-V you have to run the 64 bit versions, R2 only comes 64 bits. Visual studio is a 32 bit app, runs OK on 64 bits but it is still not the most stable piece of software I know.

Due to circumstances I had to use my laptop more and more in typical mobile situations. Also the way my colleague presses the power button, is back where he was, does his thing, closes the lid and just walks away made me a little jealous. Perhaps I should move on to Windows 7 and try Virtual PC 2009. I had played with that combination and it looked promising.

To see if this was a good idea I set up some some tests

  1. Is it possible to migrate the hyper-V virtual machines to Windows 7 virtual PC ?
  2. Can you switch networks in a virtual machine without the need of a reboot ?
  3. How does a running virtual machine survive a sleeping machine ?
  4. How does a running virtual machine survive hibernation ?

All version of hyper-V and virtual PC share the same virtual hard disk (vhd) format. They differ on the integration features, some piece of host specific software installed on the virtual machine to facilitate all communication with virtual machine. Both Hyper-V and Virtual PC have “Install integration features” as menu option.

As a test candidate I took a virtual machine with quite a history. It started its life in Virtual PC 200x as a Windows server 2003 machine with several monsters of sql 8 databases, sql reporting services and some COM custom app. Over the years it had been upgraded tot server 2008 and been living under several versions of Virtual server and Hyper –V. Not something to rebuild from scratch, just getting that version of reporting service to work is a piece of science on itself. In short: a typical real world machine. Under the several host OS-es it had seen several completely different versions of integration services. These were pretty screwed up. Every attempt to install the newest integration services resulted in messages complaining about previous versions. But the machine still worked.

Migrating

The official recipe to migrate a virtual machine is to uninstall integration services, move the machine and reinstall the integration services of the new host. But you will not find integration services under the installed programs. All attempts to uninstall form the command prompt (/Uninstall) only resulted in the same messages about previous versions.

What worked is changing the HAL (Hardware Abstraction Layer) of the virtual machine:

  • Start MSconfig
  • Boot Tab
  • Advanced Options
  • Check the “detect HAL” box

After that I just shut down the machine, copied the hard disk and created a new virtual machine in W7 Virtual PC using the copied vhd file as hard disk.

The machine booted and complained about requiring new drivers. It also required renewed activation. I installed the W7 Virtual PC integration services and allowed the renewed activation (which is never a problem with MSDN OS licenses). And after that the machine just worked fine. All integration was smooth, all software had perfectly survived the migration.

Switching networks

I can be short on this. This works just as smooth as in Hyper-V

AA1

Changing the adapter in the settings is instantaneously reflected in the status of the virtual machines adapter. The good thing is that everything works just as well with an adapter with a dynamic IP address as with one with a static address.

Sleep and Hibernate

The difference between sleep and hibernate is that in sleep mode the RAM of the PC is still powered, so actually the machine is still alive. In hibernate mode all RAM is saved to and restored from disk.

In Hyper-V the virtual machines are running on the machine level. In virtual PC you start a virtual machine as a logged in user. When logging off the virtual machines are shut down (or hibernated). Instead of logging of I tried both sleep and hibernate with the virtual machine still running. Again all news is good. All functionality completely survives both scenarios. Virtual PC is not ignorant of my actions. When hibernating it will (automatically) disable the integration services. When awakening it restores them.

To conclude

The only hurdle I had to take was the HAL setting when migrating the machine. All the rest just worked. So I repaved my laptop with Windows 7 and virtual PC 2009. (Just skip the virtual XP step unless you need a virtual XP machine). I was quite satisfied with Server 2008 (except the required full boot) but do like Windows 7 even better. VS worked well and now even works better. But that could be the result of a fresh install (there is no upgrade possible from 2008 to 7).

And now I can also close the lid of my laptop and leave the building.

Discuss (6)

Dovetail is Hiring

Posted by Jeremy D. Miller, Friday, January 29, 2010 (1,297 views)

This is a different project than the one we hired for last time.  If you've spoken to us before, please consider this position separately.

 

 

We're expanding the development team on our line of existing products. You'll be working on a small team that develops applications for large businesses using some of the latest technology. You will be involved in all aspects of solution development, including analysis, design, development, testing, documentation, and support.

We’re looking for a software developer with demonstrable C# (preferably .NET 2.0 or later) and HTML/CSS experience (ASP.NET MVC is a plus). Any experience with test-driven development or automated unit testing in general is a huge plus. Also, participation in the community (attendance of events, avid blog reader + commenter, or maybe you even have a blog yourself) will put you firmly in the running for this position. We’re looking for people that believe learning and continuous improvement are primary responsibilities of a software developer. We’re hiring motivated people for a terrific opportunity with a team of recognized .NET and agile community leaders.

Our practices and technologies include:

  • Test-driven development
  • Continuous integration
  • Behavior-driven design
  • Domain-driven design
  • HTML, CSS, Javascript (jQuery)
  • ASP .NET MVC
  • C# 3.0, .NET 3.5, Visual Studio 2008
  • SQL 2008
  • Oracle
  • NHibernate 2.x
  • StructureMap

Email us and tell us why you’d make a great addition to our team: tech-jobs@dovetailsoftware.com

This is a full-time, on-site position in our Austin, TX office. Please DO NOT contact us for outsourcing or tele-commuting.

Discuss (2)
More Posts Next page »