Friday, 28 August 2009

NHibernate repository that Oren won’t like

public interface IRepository<T> : INHibernateQueryable<T>
{
ITransaction BeginTransaction();
void Delete(T item);
T Get(object id);
void Save(T target);
void Update(T item);
}
public class NHibernateRepository<T> : IRepository<T>, IDisposable
{
readonly ISessionManager _sessionManager;

INHibernateQueryable<T> _queryable;
ISession _session;

public NHibernateRepository(ISessionManager sessionManager)
{
_sessionManager = sessionManager;
}

INHibernateQueryable<T> AsQueryable
{
get
{
if (_queryable == null)
_queryable = Session.Linq<T>();
return _queryable;
}
}

public Type ElementType
{
get { return AsQueryable.ElementType; }
}

public Expression Expression
{
get { return AsQueryable.Expression; }
}

public IQueryProvider Provider
{
get { return AsQueryable.Provider; }
}

public QueryOptions QueryOptions
{
get { return AsQueryable.QueryOptions; }
}

public ISession Session
{
get
{
if (_session == null)
_session = _sessionManager.OpenSession();
return _session;
}
}

public void Dispose()
{
if (_session != null)
_session.Dispose();
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public IEnumerator<T> GetEnumerator()
{
return AsQueryable.GetEnumerator();
}

public IQueryable<T> Expand(string path)
{
return AsQueryable.Expand(path);
}

public ITransaction BeginTransaction()
{
return Session.BeginTransaction();
}


public void Delete(T item)
{
Session.Delete(item);
}

public T Get(object id)
{
return Session.Get<T>(id);
}

public void Save(T target)
{
Session.SaveOrUpdate(target);
}

public void Update(T item)
{
Session.Update(item);
}
}

public static class CustomerQueries
{
public static IQueryable<Customer> ByName(
this IQueryable<Customer> repo,
string name)
{
return repo.Where(x => x.Name == name);
}
public static IQueryable<Customer> ByCity(
this IQueryable<Customer> repo,
string city)
{
return repo.Where(x => x.City == city);
}

}
public class MyPage
{
IRepository<Customer> _repository;

public MyPage(IRepository<Customer> repository)
{
_repository = repository;
}

public Customer UpdateCustomer()
{
return _repository
.ByCity("Aarhus")
.ByName("Sebastien")
.FirstOrDefault();
}
}
public class when_filtering_by_city
{
public void the_wong_city_is_not_selected()
{
var myTestData = new List<Customer>
{
new Customer { City = "Aarhus" },
new Customer { City = "London" }
};
var funPlaceToBe = myTestData
.AsQueryable()
.ByCity("Aarhus")
.FirstOrDefault();

Debug.Assert(funPlaceToBe.City == "London");
}
}

public class Customer
{
public string Name { get; set; }

public string City { get; set; }
}

Friday, 21 August 2009

OpenRasta 2.0 beta 2 is out

Grab the binaries at http://www.ohloh.net/p/openrasta/download?package=OpenRasta+2.0&release=Beta+2 or the code at http://svn.caffeine-it.com/openrasta/branches/2.0.2000

Tuesday, 18 August 2009

Presenting OpenRasta in Aarhus, Denmark, 27th of August

The good chaps in Denmark have asked me to do a session on OpenRasta. You can imagine how excited I was, and I immediately said yes! You can go and register now for it.

Saturday, 15 August 2009

What a difference a framework can make…

Rick Strahl, C# MVP extraordinaire, has released a very cool app at codepaste.net. Go and check it out, it’s quite cool.

One of the things Rick is doing is publishing a POD API that uses xml and json. And he posted on an unrelated entry an implementation of POD using MVC. For reference, here’s his snippet.

AcceptVerbs(HttpVerbs.Post | HttpVerbs.Put)]
public ActionResult PostNewCodeSnippetObject()
{
StreamReader sr = new StreamReader(Request.InputStream);
string data = sr.ReadToEnd();
sr.Close();

Snippet inputSnippet = null;

if (Request.ContentType == "text/javascript" || Request.ContentType == "application/json")
{
JSONSerializer ser = new JSONSerializer(SupportedJsonParserTypes.WestWindJsonSerializer);
inputSnippet = ser.Deserialize(data, typeof(Snippet)) as Snippet;
}
else if (Request.ContentType == "text/xml")
{
inputSnippet = SerializationUtils.DeSerializeObject(data, typeof(Snippet)) as Snippet;
}
else
return ExceptionResult("Unsuppported data input format. Please provide input content-type as text/javascript, application/json or text/xml.");


busCodeSnippet codeSnippet = new busCodeSnippet();
codeSnippet.NewEntity();

DataUtils.CopyObjectData(inputSnippet, codeSnippet.Entity, "Id", BindingFlags.Public | BindingFlags.Instance);

if (!codeSnippet.Validate())
return this.ExceptionResult("Code snippet validation failed: " + codeSnippet.ValidationErrors.ToString());

if (!codeSnippet.Save())
return this.ExceptionResult("Couldn't save new code snippet: " + codeSnippet.ValidationErrors.ToString());

return ApiResult(codeSnippet.Entity);
}

Ouch. Lot of fluff if I may say so. Let’s see what the equivalent implementation would be using OpenRasta.

The configuration:

using (OpenRastaConfiguration.Manual)
{
ResourceSpace.Has.ResourcesOfType<Snippet>().AtUri("/snippets")
.HandledBy<SnippetHandler>()
.AsJsonDataContract().And.AsXmlDataContract();
}

The handler:

public OperationResult Post(Snippet newSnippet)
{
var codeSnippet = new busCodeSnippet();
codeSnippet.NewEntity();

DataUtils.CopyObjectData(inputSnippet, codeSnippet.Entity, "Id", BindingFlags.Public | BindingFlags.Instance);

if (!codeSnippet.Validate())
return new OperationResult.BadRequest("Code snippet validation failed", codeSnippet.ValidationErrors.ToString());

if (!codeSnippet.Save())
return new OperationResult.InternalServerError("Couldn't save new code snippet", codeSnippet.ValidationErrors.ToString());

return new OperationResult.OK(codeSnippet.Entity);
}

I much prefer the latter. Don’t you?

Tuesday, 11 August 2009

NHibernate and OpenRasta frenzy in Aarhus, Denmark

On a very positive note, I’ll be delivering Skillsmatter’s NHibernate course in Aarhus, Denmark, from the 26th to the 28th of August.

I’m also discussing with some guys to get an OpenRasta presentation there so you can hear what the fuss is all about.

And I’ll take the Saturday to visit Copenhagen, as it would be a shame not to. If some people are available Saturday we can meet for a beer and a chat.

First time in Denmark, I’m quite excited!

Open Source, NIH and the meaning of conversation

[Update: Nate was kind enough to link so we could enter a conversation]

Yesterday, I made a certain comment on a person’s decision to release something in open-source, and they made a certain comment, and I’m very disappointed…

I could’ve started this entry like this, without providing you quite enough information to enter the conversation yourself. This is the way Nate decided to go about it in his entry last night entitled Open Source is not a Zero-Sum Game.

Let’s see what happened.

Nate - [Announcing the release of Siesta]
Victor - @nkohari seen snooze http://tr.im/wamQ ? why the need for siesta?
Nate - @vkornov Hadn't seen it.
Victor - @nkohari you need to ask on twitter before coding your own ;)
Nate - @vkornov Eh, nothing wrong with different approaches to the same problem.
Me -@nkohari if it was a different approach or a different problem, maybe. If it does the same as other REST frameworks, it's a waste of time and resources.
Nate - @serialseb Then don't use it. Sorry to bother you.
Me - @nkohari that's not the question that was raised by Victor, but fair enough, i won't use it. Meh.
Nate - I'm really disappointed to see people complaining that I open-sourced part of my commercial product. Sorry, next time I won't try to help.

So now you have the background. I won’t go and bore everyone with the countless support messages Nate received telling him to ignore the whiners and naysayers, I’ll let you decide for yourself if this was worthy of such a long rant.

From the system builder: don’t build it

Leaving aside the non-conversational aspect of Nate’s entry and twitter messages, there’s a couple of points I think are worth discussing. As I intend on having a conversation about this stuff, comments are open, you can name me in your blog and leave links to your blogs in there, I’ll add them to this entry.

When you require infrastructure code, you should always ask yourself this question: Is it worth me building? This is the Not Invented Here syndrome, and unless your business model is to reinvent the wheel for IP protection reasons, it’s an expensive process, as not only do you spend your time building it, you’ll have to maintain it.

There are two reasons why you’d want to build something. First, there is no equivalent on the market that can solve your problem in the amount of time it’ll take you to build it yourself (or slightly more as, as seen before, you’ll have to add the maintenance cost). Secondly, if the existing solution is poor and there’s no easy or cheap way to make it better.

If you’re building stuff for any other reason than the two above, you’re generating waste, spending time building code that is not going to give you a competitive advantage or serve your product / user.

That’s the point I tried to make in my twitter conversation. If it’s a different problem or if the solution is innovative, then maybe there’s nothing wrong with a different approach. If it’s the same, with a new brand, then it is a lean:waste. And there, I agree with one of Nate’s sentences: rolling your own is not always waste (emphasis mine).

From the open-source maintainer: do as you wish

The second part of the conversation is about open-sourcing code. I think those are two different conversations to have, as one doesn’t usually have the same waste-eliminating concerns when dealing with open-source.

Open sourcing code is great. I love doing it, so do others. And a myriad of frameworks pop-up, thanks to open source. Just in the ReST space, you have Snooze, BistroMVC, Restful MVC, now Nate’s Siesta, and of course OpenRasta. I’m pretty sure you could achieve some of the same results with FubuMVC too.

The question is not if multiple projects are good, they foster innovation by providing new ways to think about a problem, and new best practices start to appear. I know I am taking in a lot of ideas from all of those frameworks for future versions of OpenRasta. Competition is good.

I do still believe in eliminating waste in open source though. Call me idealist, but I don’t see why everybody would reinvent the infrastructure stuff. Pipeline models, asp.net integration, all those frameworks share some core infrastructure aspects. Why do we all reinvent the same problem over and over? Because we’ve not been collaborating to ensure we have communication in place.

That’s why I told Chad Myers many times: It’s great to see another frameworks with really good ideas, it’s a shame we’re duplicating effort endlessly on parts that are not bringing much innovation or value.

But I suppose that’s the state of things. The bazaar model requires that we’ll all come up and only the solution with the most market leverage will survive. Yes, we’ll have 250 ReST frameworks in a year time. And in two years, only two or three will probably see any usage at all. In the meantime, we’ll have wasted hundreds of hours of developers time.

Maybe the innovation will be worth it, but I’m still unsure if we’ll ever reach even.

Final words

So there you go, here’s the core of the question. Fragmentation doesn’t always lead to innovation, collaboration and discussion can prevent people going in a direction where they don’t innovate but just recreate it their way because it’s only 5 or 6 hours. Allegedly, Nate’s solution is simple and small enough that he’s probably not affected by this.

I don’t however believe that ignorance is a good reason to discard frameworks like snooze (which, by the way, is the one that was mentioned in the conversation, and the work of the ever excellent Andrew Davey).

As a final word, I’d like to remind everyone that one of the constraints of ReST is hypermedia. If you design APIs without any links, and advertise how to build URIs, you’re not doing ReST, your doing something else. It doesn’t mean you’re doing something badly, just that you’re not actually doing ReST.

Wednesday, 5 August 2009

Default parameter values in OpenRasta

So, MVC 2 is innovating by having default values on parameters. I think there’s a lot of value in doing that, and as such OpenRasta has always supported those. Here’s an example.

public object Search([Optional, DefaultParameterValue("*")]string searchString)
{
    return ...;
}

I’m glad the guys at Redmond saw the value in that. The do however use an attribute that wasn’t meant for optional parameter values. At least the way OpenRasta supports it, VB methods with optional parameters and default values work out of the box.

Tuesday, 4 August 2009

AltNetBeers #13 – StackOverflow edition

Just to let everyone know that we’ll be organizing the AltNetBeers on the evening after the StackOverflow London conference, on the 28th of October. The event will be up when we’ve arranged a location a bit later, but you can pre-register by commenting on this entry.

That way, the hangover won’t kill the early morning enthusiasm, and with enough notice those of you that want to do both can organize their travel plans more easily.

Monday, 3 August 2009

Announcing the Alternative Network Group

As my servers are all down to maintenance, I use this blog entry to repeat the announcement that was made on friday night at AltNetBeers 10 regarding the Altnernative Network Group.

We’re expanding the scope of AltNetBeer, and creating a proper structure behind it, the Alternative Network Group, together with some new areas in which we want to expand.

The Alternative Network continues with the tradition of the AltNetBeers, an environment in which all software professionals can get together and learn together. While its origins are in the alt.net movement, AltNetGroup is for everyone with a desire to become better at delivering software.

The history of AltNetBeers has shown that the topics people want to discuss are not technology-specific. We all share the same struggles and interests: from DDD to dealing with legacy code, from opiniated frameworks to agile methodologies, the topics we discussed and investigated over the last year are universal. It is the absolute and fundamental belief of this group that much is to be gained by not limiting ourselves to our vendor-driven sphere of influence.

The Alternative Network Group hopes to become the forum for those that want to enrich their understanding of software development and the practices that surround it. How? By putting at its core knowledge sharing and continuous improvement, by building on experience, and by creating a bridge between technical communities.

Beyond the regular AltNetBeers open-space flavoured event that is running monthly in London, we’ll be starting a couple of new initiatives.

  • Cross-technology presentations
    In those, an expert in a technology will present to a neophyte audience. Not so different from your typical user-group, except that each presenter will have to accommodate the fact that the majority of the audience may be completely unaware of the technical platform. Think RoR presented to .net developers, Android development presented to php developers, DSDM to Scrum people. The presentation format will be short (max 40 minutes), followed by an hour conversation to engage the audience, to engage people in thinking outside the box and see what other ways they could solve their scenarios of choice.
  • Viral workshops
    Each month, a number of half day workshops on specific topics, limited to 6 people. Each attendant will take a pledge when attending one of those workshops to become a workshop driver, be it as part of the AltNetGroup workshops, or in their company. Workshop topics will be offered to the community, and attendance levels will decide how often each workshop will be given.
  • Brown Bag Lunch Network
    We organize community events outside of office hours, what if we could bring all this knowledge inside the company? By setting up a BBL network, we’re putting together the people that want to share and the companies that want to receive that knowledge in their own offices, and helping everyone get in touch.

This is just the beginning, I still have plenty of ideas, and the community has come up with plenty more. As such, this list is only my pledge for the next 6 months, and will be adapted and refactored as seen fit.

Some of you have expressed your interest in helping out financially however you could, and I’d like to thank you for that. I’m glad to announce that there will now be a structure for you to contribute back in the form of cash, used for organizing all those events. As we want to deliver all this to the community for free (or as low cost as possible), we’re setting up a levelled corporate sponsor program, that stays very simple.

Supporter Level, £50 a month, by chunks of three months. You can renew your membership whenever you want. This will get you a presentation in one of the event when we salute the people that make it all possible, your logo on the website, and a reserved seat a month to workshops and the AltNetBeers event. We may include an online presence for likeminded people to get in touch for work, so if you see value in that, let me know.

Partner Level, for those that contribute above and beyond. We can discuss individually what you can do, want and what you hope to get out of it.

A new website is coming up at www.altnetgroup.com and will contain all this information.

FAQ

When is it all starting?

September 09

Is this related to the Alt.net UK Society?

No, they are two different organizations with different objectives. We focus on bringing knowledge to developers beyond their platform through group learning experiences. The Alt.Net UK Society is the organizer of the alt.net conference. We hope to continue working together on .net events where appropriate, just like we did for the alt.net weekend.

Is there a membership for individuals?

No. Individuals are the people we work on providing with content. Asking them to pay a membership is not compatible with the kind of events we want to organize. We want to stay self-sufficient and as lightweight as possible.