Nancy takes another step forward

The say time flies when you are having fun and nothing could be more true when working on Nancy. Two months have already passed since we started work on 0.8.0, a release that was suppose to roughly take around 4-5 weeks to complete and consist mostly of diagnostics related changes. Boy were we wrong.

A community release

What did happen was that the awesome community around Nancy kept providing use with feedback, requests and, most of all, code! The 0.8.0 release was not created by me and Steven, but by the community at large.

A quick look at the comparison of 0.7.1 and 0.8.0 shows that a total of 19 authors and 186 different commits contributed code to this release and made the 44 work items happen. If you add all the people that provided feedback on the user group and on twitter then the number is, a lot, greater.

So thank you to everyone that helped make this release possible!

How much awesome can you stuff in a release?

Apparently quite a lot! The list of changes are too great to list in this one single blog post, but fortunately we make good use of the GitHub milestone systems and you can view the full change log at our repository.

However, here are some of the highlights of this release

  • Static content conventions – Yes! We finally have a good user story for static content so you no longer need to jump though hoops to serve static contents. These conventions are, of course, configurable and comes with a default one that looks for stuff in /content.
  • Cross-site request forgery protection – Make sure you can trust the data that is sent to your application.
  • Testing improvements – Added a new configurable bootstrapper in the Nancy.Testing project that helps you control the fine grain of your test environment with the help of a nice API. We also added a bunch of new extension methods and updates.
  • Forms authentication improvements – You can now login/logout without having to performe a redirect, this is really useful in ajax scenarios.
  • Error handling hook and error pages – A pipeline where you can handle errors in your application and also support for rendering custom error pages.
  • Access to captured parameters on the context – Enables you to gain access to captured values from inside filters.
  • ProtoBuf support – A new Nuget that enables you to support ProtoBuf (de)serialization in your routes and model binding.
  • And sooooo much more – Go check it out!
  • All of this and we’re still on the super-duper-happy-path!

Sporting new swag!

With this release we also introduced the new Nancy logo and website! The awesome Nicolas Garfinkiel stepped up to the plate and awed us with his logo suggestion. He has been great to work with and managed to cope with the swarm of tweaks me and Steven threw at him! Not only that but he’s been working blazing fast and it only took us a week-ish to iron out the rough spots in the draft and get a polished version done!

We are really pleased with it and soon you will be able to get your hands on all the logo goodness, you’ve been wanting to (right?!), at our new Nancy.Portfolio repository. The repository will contain the logo in various formats and resolutions and well as a usage guideline. We just need a bit more time to put the finishing touches on it.

In case you’ve not seen it yet, this is one of the compositions of the logo

nancy-blog-logo

Beautiful, isn’t it?!

I plan on dedicating an entire blog post about the logo in the next day or so, so keep an eye out for more information!

Onwards!

Don’t worry, we’re not running out of things to do, in fact we’ve already staked out part of 0.9.0 (there’s even some planning on 0.10.0 up on GitHub). We’re going to try really hard on making the release cycle shorter this time because we really want to get the new, awesome, stuff into your hands as quickly as possible!

By the community, for the community

I would like to thank everybody that supports Nancy, no matter how you do it. People are building commercial produces, going to conferences and talk about Nancy, blog about it, contribute ideas, code and feedback. Nancy is truly a product by the community, for the community and for that we thank you all!

Getting fancy with Nancy – Introduction

Right from very first day that I announced Nancy to the world, the pace that things have moved forward has been nothing short of amazing. Nancy was always meant to be developed right out there with the community and let me tell you that I have not been disappointed, the community answered the call. Pull request nr. 116 was sent in the other day and over 26 people (with a couple of more having pending requests) have contributed code to Nancy – some of them on multiple occasions.

Since then Nancy has gained an impressive feature lists such as bootstrapping capabilities for all the major Inversion of Control containers, view engine support (spark, razor, ndjango and a Nancy specific engine), hosts for asp.net, WCF, self-hosting and even one of the (if not THE) first OWIN compatible host, cookies, sessions, embedded views, pre- and post-request pipeline, security (authentication and authorization) and many many more. The list keeps on growing.

There have also been several individual and companies that have started writing applications on Nancy, ranging from simple proof of concept applications to actually taking Nancy into a production environment is software that’s sold to customers. We’ve also gotten to see Nancy run on mac and Linux thanks to mono support and we think that’s just awesome!

So what’s the fuzz all about?!

The goal of Nancy is to provide a no fuzz, low ceremony framework for building web applications. One of the key concepts that’s applied when working on Nancy is that everything should have a “super-duper-happy-path” implementation, you shouldn’t have to jump though hops to write your websites there should be a sensible default for everything. Simplicity is key, but not at the expense of power.

At first glance you wouldn’t know it, but pretty much everything in Nancy is customizable. It’s intentionally been designed to stay out of your way, but should you find yourself in need to change a specific behavior Nancy will make it as frictionless as could be.

Right from the get go, Nancy was built to not rely on a specific environment to be able to run. We built the concept of host adapters and they site right in between Nancy and what ever environment she might run on. Out of the box we currently supply hosts for running on top of ASP.NET, WCF, OWIN and a self-host (built on httplistner), but the list is sure to expand and writing adapters is easy.

There is no dependency, what so ever, on System.Web from the Nancy core assembly so you can, without any problem, embed Nancy in your applications and so on. ReST-based end-point in your application? Sure why not?!

Bla, bla, bla – show me the codez!

Alrighty then. To give you an idea of how it is to work with Nancy, we will be building a simple Hello World (surprise!) Nancy web application. The application will be built to run on ASP.NET, but it could just as easily have been running on any of the others hosts (just swap it out, no code changes needed).

To get started create a new ASP.NET Empty Web Application project (don’t worry, we have our own project template but let’s skip those and get right to the fun stuff). Once you’ve created the application it’s time to grab Nancy. You could visit out repository to download the source and build the binaries, or you could choose the easy way; use NuGet to grab the bits we need.

We are going to go with the NuGet packages, so grab the Nancy.Hosting.Aspnet nuget. Not only will this install the adapter required to run Nancy on ASP.NET, but it will also register the adapter in your web.config and grab the Nancy core nuget.

That’s it. You have the foundation of a Nancy application running on top of ASP.NET. Now you need contents. So let’s add a module to our project (modules can be added anywhere in your project, Nancy will find them for you).

What you are looking at is a module that responds to a GET request to the root path of your application. When an incoming requests matches those criterion, Nancy will respond with the text “Hello World”. Run the application and verify that I’m not kidding you – it really is as simple as that!

That’s all will show you in this post. In following posts I will be sure to take you on a journey in the world of Nancy and show you things like POST, PUT, DELETE and HEAD requests, injecting dependencies into modules, using response formatters, grabbing parameters from the requested route, complex route syntax, view engines, model binding, before/after request handling (both on request and module level) and much, much more.

Nancy on the web.

If you want to talk about Nancy you can find us on Google Groups or on Twitter using the #NancyFx hashtag. You can also reach me on twitter @thecodejunkie

Nancy, the little community-powered framework that could

Two months ago, on the day, I first announced Nancy here on Elegant Code as my new open-source project. I could never have anticipated the chain of events that would take place during the following two months. My tweet about the blog post got re-tweeted more times than I can remember and the post filled up with, mostly, awesome feedback.

It took about and week and then Nancy got the first pull request on her github account and from there it started to build up momentum quite fast. At the time of this writing there’s been 53 pull requests, by about 20 different people, for all kinds of features, bug fixes, custom hosts… you name it. Not bad, eh?

Not only that, but Nancy has managed to pull together a nice little community, over at Google Groups, where the future of Nancy is being discussed every day. She’s also getting some attention on Twitter and we’re trying to gather it all under the #NancyFx hashtag and seems like every day there is a new face popping up.

In the initial commit there were a couple of abstractions and light extension points in place for things like custom hosts, view engines and response formatters. These turned out to be a very smart move, because the community really embraced and ran with them. Let me recap some of the things that has happened since day zero

  • View engines; there are currently support for Spark, Razor, NDjango and Static templates. We did have support for NHaml for a while, but that community seems to have gone into hibernation, so the decision was made to pull it and not waste dev cycles on it until there was a demand
  • Inversion of Control integration; this has been one of the big one. Right from the very first beginning I wanted Nancy to be a self composing framework, that is have a small internal container that glued the framework together at runtime. I also wanted the possibility to register module level dependencies. It took a while and a couple of iterations, but we finally settled on a design and made TinyIoC the internal container. It was very important that it was a transparent experience to the end user and unless you have a need for it, you never know it’s there. Not only that, but thanks to community contributions we’ve managed to create hooks (known as bootstrappers in Nancy) for all of the major players such as StructureMap, Autofac, Unity, Ninject and Windsor. Using one of these container with Nancy is a very easy thing to do and only adds one more file to your project
  • Response formatters; one of the powerful features in Nancy is the response model and how it lets you return different kinds of things and leverages implicit cast operators to hide the complexity behind it. Thanks to the awesome Nancy community we now have the capability to return JSON, XML, images and perform redirect responses. It’s super easy to write a response extension and hook it into Nancy, so if you have any ideas….
  • Bug fixes; yeah I know, it’s shocking, but it’s still true. Every now and then someone finds a bug but, more importantly, most of the time the same person is part of contributing a patch to resolve it!
  • Hosts; Nancy has been designed with the idea of being able to run in multiple environments and shipped with a host to run on top of ASP.NET. Right now we have additional hosts for running Nancy on a WCF host and on a stand alone host. There are more of them on the way
  • HEAD requests; the first release of Nancy supported GET, POST, PUT and DELETE requests, but thanks to a clever little contributions she now also serves up HEAD requests
  • Cookies; not he ones you can eat….
  • Cookie based sessions; I think this is also self describing.. oh… yeah they are encrypted in case you were wondering!
  • Mono; we’ve started to seriously look at getting Nancy to run on top of the up coming mono 2.10 release (we need the improvements they’ve made to the dynamic keyword) and have already managed to run the sample application on both Linux and Mac OSX. Moving forward mono is going to be a supported and equally priorities platform to support
  • Visual Studio templates; these are still work in progress but right now I have the ability to new up a new Nancy project, based on the html5boilerplate … and we have a bare bone template in the making
  • Buildscript; a couple of days a go we added what every self respecting open-source project needs; a build script. We choose to use Rake (that’s a ruby powered format, for those of you that’s never seen it before) and make use of the excellent Albacore gem, but the awesome Derick Bailey

I’ve probably forgotten a bunch of things, there’s been so much going on that I can’t remember it all without looking at the commit history! That said, there are still things we want to put in place and there are already extensive discussions on the user group about them

  • Security
  • Content negotiation
  • OWIN hosting (we’re keeping track of the OWIN 1.0 specification)
  • Self-hosting (Benjamin van der Veen, if you are reading this – maybe Kayak can be a candidate!)

The one thing that we can’t seem to pull of

Is to find a designer to design a proper logo for the framework! We are in desperate need to get an awesome logo that we can put everywhere and start creating a website. So if you know any good designers that wouldn’t mind putting in some time in designing an awesome logo for an open-source project (read pro bono) and please tell them about us and about Nancy! A while back I created a post about the Nancy logo on our user group. It contains some information on the philosophy and goals for a logo for Nancy. I can’t stress enough how much I would appreciate if you took this and shared it with your designer friends!

As always, if you want to ping me either drop me a comment right here on the blog or find me on on Twitter account @TheCodeJunkie

… I can’t help to wonder what Nancy will be like in another two months!

Introducing Nancy, a lightweight web framework inspired by Sinatra

For a couple of weeks I have been keeping myself busy with open-source stuff. One of the things has been to spike out a web framework idea and later on turn it into a real project. The project is inspired, but not a clone, by the Sinatra web framework built on Ruby. The name, Nancy, is a reference to Nancy Sinatra, the daughter of Frank Sinatra.

There are quite of lot of things that I want to put into the framework, but it is functional in its current state. One of the goals for Nancy is to make it run on other environment and platforms, other than ASP.NET / IIS and there are spikes taking place to run it on Mono with FastCGI, making it possible to run on a bunch of other platforms. However, although this is the goal, the current source code does not provide any helpers to make that possible. Right now it only ships with an IHttpHandler that acts as an adaptor between ASP.NET / IIS and the Nancy engine.

The project is built using C# and makes use of xUnit, MSpec and FakeItEasy

The key component in a Nancy application is the modules. This is where you create actions, which are handlers for a given request type at a given path. Let me show you what I mean

public class Module : NancyModule
{
    public Module()
    {
        Get["/"] = parameters => {
            return "This is the site route";
        };

        Delete["/product/{id}"] = parameters => {
            return string.Concat("You requested that the following product should be deleted: ", parameters.id);
        };
    }
}

What you are looking at here is the foundation of a very small application that will responde to GET requests to the root URL of the site, and DELETE requests to /products/{id} where {id} is a parameter placeholder. All parameters will be captured and injected into the action, like you see with parameters.id.The entire route handling mechanism is swappable, so you could write your own handler that were able to interpreted the route syntax that you prefer. A module can also be declared with a module path, meaning that all action routes, that you declare in the module, will be relative the module path.

For example if you were to do

public class Module : NancyModule
{
    public Module() : base("/foo")
    {
        Get["/"] = parameters => {
            return "This is the site route";
        };

        Delete["/product/{id}"] = parameters => {
            return string.Concat("You requested that the following product should be deleted: ", parameters.id);
        };
    }
}

The the application would respond to requests sent to /foo and /foo/product/{id}. You can of course have as many modules as you want. Nancy will detect them all and figure out which action that should be invoked. There are also some nice ticks in there for return values. In the examples above you get the impression that you are expected to return a string, and this is not the case. In fact each action returns an instance of a Response type. What you are seeing is the result of some implicit cast operators. There are a couple of them declared

public class Module : NancyModule
{
    public Module()
    {
        Get["/"] = parameters => {
            return "Returning a string";
        };

        Get["/404"] = parameters => {
            return 404;
        };

        Get["/500"] = parameters => {
            return HttpStatusCode.NotFound;
        };
    }
}

All of these will work and send back a valid HttpResponse (including headers) to the client. You can of course explicitly return a Response instance which opens up for some nice customization. A module in Nancy also declares a pair of properties called View and Response. Both of these have an interface return type and each of them are empty marker interfaces that you can use to wire up extension methods. The View property is meant to be used for view engine integration and in an unpublished spike (still needs some more work) I’ve wired up the http://www.sparkviewengine.com/ so that Nancy is able to process spark files. This is an example of what that looks like

public class SparkModule : NancyModule
{
    public SparkModule()
    {
        Get["/user/{name}"] = parameters => {
            return View.Spark("user.spark", parameters);
        };
    }
}

Of course all of this is work in progress and the syntax might change. The goal is to support all of the popular view engines and if you are up to the task of implementing support for one of those, please let me know – I would love the help!

The Response property is meant to be used for extensions that help format the response in different ways. A test I have running locally is an extension method that enables me to return json formatted data.

public class JsonModule : NancyModule
{
    public JsonModule()
    {
        Get["/user/{name}"] = parameters => {
            return Response.AsJson(someObject);
        };
    }
}

Of course I would like for Nancy to ship with a healthy set of these response helpers, so feel free to chip in!

Oh, there is one last property that you can use and that is the Request property which gives you access to the current request information, so that you can use it from inside of your action handlers. Right now it is limited to the requested path and verb, but the goal is to have a rich representation of the current request – what stuff would you like to see in it?

public class RequestModule : NancyModule
{
    public RequestModule()
    {
        Get["/"] = parameters => {
            return string.Format("You requested {0}", Request.Path);
        };
    }
}

One thing I would like to mention about the action handlers and their routes. If there are two or more routes that are a match to the current request, Nancy is going to select the one that has the most matching static path segments before a parameter placeholder is reached (but all segment has to be filled!). What does this mean? Take the following routes

/foo/{value}
/foo/bar/{value}

The first route has one static path segment (/foo) and the second one has two (/foo/bar). So for a request to

/foo/bar

The first route will be selected, but for

/foo/bar/baz

the second route will be selected. It also important to understand that in Nancy, all path parameters are greedy, not like in ASP.NET MVC where you can have one greedy (indicated by a star *) and has to be at the end. If you define a route

/foo/{value1}/bar/{value2}

you can invoke it with

/foo/this/is/some/segments/bar/and/then/some/more

and you will end up with

{value1} = /this/is/some/segments
{value2} = /and/then/some/more

Of course, like I said before, this is how the default route handler works and if you don’t like it you can write your own, all you have to do is implement a single interface and tell Nancy to use it.

So before I end this post, let me tell you about some of the things that are planned to be included in Nancy as soon as possible

  • A much richer request object. Nancy uses it’s own Request object and is not tied down the the one found in ASP.NET. I want to support a rich and easy to use model for request information. If you have any suggestions on the structure of this object, please let me know
  • The ability to inject dependencies into Nancy modules. I want you to be able to wire up Nancy to use your favorite IoC and have Nancy resolve constructor dependencies of Nancy modules
  • Conditions on actions. I want to add an optional predicate on actions like Get[“/foo”, () => somePredicate], to give Nancy the ability to select actionsat runtime. For example you might have two identical actions define, but you add a predicate on one of them that made sure that it was only selected if the client was a mobile device. Actions that has a predicate defines should have higher priority than those that do not
  • View engine integration. Like I said, the Nancy modules comes with the View property, which is of the type IViewEngine, where you can hook up view engine support. All you need is an adapter that returns a string (or a Response instance). Please let me know if you want to chip in and help wire up one or more view engines
  • Ship with a nice bunch of response formatters. These are created by attaching extension methods to the IResponseFormatter interface, which is the property type of the Response property on a Nancy module. I think the formatters should follow a naming convention where you name them As<something>
  • Self-composed framework. What is mean with this is that I want to build Nancy on top of a tiny, internal, IoC that is used to compose the framework at runtime. It should be exposed in a simple way so that you could swap out components (such as the route matcher, or module discovery mechanism) as you please
  • Request and Response interception. The idea is to provide a lightweight way to intercept Nancy requests before they hit the Nancy application and let you either pass the request to the Nancy application or prematurely send back a reply. Combines with the ability to intercept Responses sent by the Nancy application, it should give a nice way of extending Nancy with features like logging and caching. You can think of this as a sort of IHttpModule mechanism
  • NuGet presence
  • Command line (powershell?) support for spawning up a Nancy application project
  • Provide self-hosting somehow

There are a bunch of other stuff I have in my head, but I have to give them some more thought to distil proper ideas from them. But please, let me know if you can think of anything more! I want to keep Nancy lightweight and easy to use, so it will probably never be as open-ended as ASP.NET MVC, FubuMVC or Manos de Mano – but we’ll have to wait and see!

You can find the source code at my Nancy repository at GitHub. You can also reach me on Twitter at @TheCodeJunkie. If you want to talk about Nancy drop me a line in the comments or on Twitter and we can move onto e-mail, gtalk, skype or messenger if needed! I hope you like where Nancy is going!

The Web is Not Platform Independent

There was a time when you wrote a web site and you targeted IE6.

That time has long passed.

When you really only had to target IE6, you could pretend the web was platform independent.

The truth is now the web is neither, nor will ever be platform independent.  It’s just an illusion based on the simple notion that browsers basically just render HTML.

pegi

How many platforms are there then?

This is a surprisingly difficult question to answer.

Back before the web really took off there were basically 3 platforms to develop an app for: Windows; Unix/Linux; and Mac.

When we answer this question for the web, really we have to look at browsers as if they are the operating system.  Since the same browser exists on multiple base OS’s but could be different, we have to count each combination of browser and OS as a potentially separate version.

Windows: IE6, IE7, IE8, IE9 (beta), Firefox, Chrome, Safari

OSX: IE, Firefox, Safari (more?)

Linux: Firefox, Chrome

Android: Webkit

iPad, iPhone: Safari

I don’t have nearly every combination listed, but this is what I would consider a good coverage for any kind of public facing website.

Oh, don’t forget to cross this again with localization and globalization, because you might have a localization problem that only happens in a certain language in a certain browser on a certain OS.

Not just rendering level differences

It is also very interesting to consider that a web developer now has to consider how their site will not just render, but be used on a mobile platform. 

Consider how Google released an iPad version of Gmail.  And although, you may not really care if your site works on an iPhone or an Android phone, you probably should start caring about how it works on tablets like the iPad, because that market is only growing.

If you have a website that doesn’t work on someone’s iPad when they are shopping online, do you think they will get up, go turn on the computer, and go to your site to make the purchase or they will buy from a different site with a few touches?

With a phone size resolution, the considerations are even more important.

Tools help me make the web platform independent

No tool exists right now that can handle the non-technical aspects of platform independence for your web application, but let us imagine for a second that a library like JQuery really made your javascript platform independent.

If we were to hold onto that shaky assumption, we would need to make sure that we never wrote javascript that wasn’t written through the JQuery API.  (Which happens to be an extremely leaky abstraction over javascript, CSS, and the DOM.) We would still have to make sure our HTML and CSS tags were platform independent.

So even if we could get parts of our development to be mostly platform independent, we would still need to test on all of the major platforms, because we could not rely on the platform independence.

Now, don’t get me wrong here.  I love JQuery.  It makes the job of a web developer so much easier.  But, there is an important distinction.  APIs and libraries like JQuery make it easier to write platform independent web code, but they don’t make our code platform independent.

What does all this mean?

We’ve gotten to the point where the most platform independent technology you can use is either Flash or Silverlight.

I’m not sure if this is the future of development, but it very well might be.

One important point to draw from this realization is that we shouldn’t necessarily choose to make our application a web application, because we need it to be platform independent.  It seems like about 5 years ago, the web became the default choice, because it was better to have platform independence than a rich UI.

Hopefully, for the sake of web developers some of these paths die off or converge, or that standards compliance becomes so good that you could really write code for one browser and expect it to work on all the others.

As always, you can subscribe to this RSS feed to follow my posts on elegant code.  Feel free to check out my main personal blog at http://simpleprogrammer.com, which has a wider range of posts, updated 2-3 times a week.  Also, you can follow me on twitter here.

JetBrains Web IDE

As I already mentioned in a previous blog post, I’m kind of (re-)learning HTML and CSS. The best way for me to pick things up again is by getting my hands dirty and work myself through a simple example. So I decided to work on some sort of prototype of a web application without using any web framework like ASP.NET MVC, Fubu MVC, Ruby on Rails, etc. … Just plain old HTML and CSS, like the Internet gods intended. I also didn’t want to suck all the fun out of it either, so I decided to use Web IDE from JetBrains as my IDE for churning out this prototype.

I must say that I was pleasantly surprised by some of the features that this IDE has to offer. The first and most obvious one is probably intellisense that just works as expected.

image

Also notice the on-the-fly code inspection (colored marker bar on the right) that should be familiar when you’re a Resharper addict like me. Web IDE provides W3C XHTML/CSS validation while working in the editor which is really useful.

image

Being the uncertain type, it was also nice to see all the familiar refactoring features from Resharper being available as well. Renaming a class or id is just a breeze. All the corresponding HTML or CSS files are consistently updated.

image

Navigation is there as well (CTRL-N and CTRL-SHIFT-N).

image

This looks just like Resharper for web developers, but there’s more. At first, I had all the HTML and CSS files including all the image file in the root folder of the project. I wanted to divide and conquer by putting the images and CSS files into their own separate folder. As I prepared myself to change all the references in the HTML files, Web IDE did that all for me when I dragged the files to their final destination. Now I didn’t had to go over all the HTML files and manually change the links. How cool is that!

Web IDE also provides source-control integration Subversion, Git, Perforce, etc … and that’s just the tip of the iceberg. While working on the prototype of the web application, I mostly focused on the layout and not so much on the behavior so I didn’t use much of the JavaScript capabilities. But I was told that it is comparable with the JavaScript features in RubyMine as described by Peter in this blog post. This is something that I’m going to explore when I start learning more about JavaScript :-).

Although being the first version and still in beta, the IDE seems pretty stable and I couldn’t notice any performance hiccups so far (which cannot be said for all IDE’s these days).

I do hope that there will be some support for ASP.NET or other view engines like Spark, NVelocity, etc. … in future versions. In fact, I still silently wish that JetBrains would come up with an IDE for .NET. Being realistic about it, I don’t have high hopes for something like that coming out but it would totally rock if they decided to build one. Sweet dreams 🙂

Bottom line, when you’re doing web development in Visual Studio, make sure to also check out Web IDE. It will probably help you to become more productive along the way.

CSS Basics: The Box Model

If you’ve been using CSS for a while, then this post will probably teach you nothing new. I just wanted to state the obvious even if I’m the only one who benefits from it.

While I was (re-)learning CSS, I came across these two properties called margin and padding. At first, they seem to be doing the same thing namely providing space between HTML elements. But although they seem to fulfill the same purpose, there’s a clear distinction between the two.

image 

The margin is intended for providing space between outside HTML elements or the sides of the page. Padding is used for providing visual space between the content and the border of the box.

Some margin, no padding
Some padding, no margin

 

The first example provides a margin to add visual space between the border and the parent element. The second one provides space between the border and the content.

I agree that this is trivial, but it matters to understand the difference between these two properties when using CSS.

Open Source Silverlight video players

image Lately I’ve been spending a lot of time in the Silverlight video space.  Both with writing the video chapter for my Silverlight 4 book as well as at work.  Creating a basic video player is straight forward (link 1 | link 2), have a button to play, a way to control the volume, a scrubber to show the position of playback, and of course an area to view the video. 

Once you get beyond the basic requirements, the “basic video player” becomes very involved.  A few questions that will need attention are:

  • “How do you handler markers?”
  • “How is streaming video handled?”
  • “What do you do an an error?”
  • “What’s the strategy for buffering?”
  • “Can the video player support Smooth Streaming content?” (this is a whole different conversation)
  • “How does the video player handle Closed captioning?”

And on and on the list goes.  At some point (hopefully in the analysis phase) you should ask is it better to build or buy.  If you decide to build, give me a call ;), but before you do I would encourage you to take a look at the following open-source (free) Silverlight video player options.  If nothing else, these players are great place to start.

I’ll start off with the three best options, then highlight other projects I am less familiar with.

Silverlight Media Framework (SMF)

http://smf.codeplex.com/

This is so much more than a video player, it’s an entire framework.  Developed by Vertigo in coordination with Microsoft, SMF has been used on the largest, most watched, Silverlight video players to date.  Wimbledon, NFL’s Sunday Night Football, PDC live keynote, and the NBC’s Vancouver Olympics video players, to name a few, all use SMF.  To say it’s robust would be an understatement.

Other than the standard video player controls, here are additional highlights of SMF:

  • Smooth Streaming support – includes the Microsoft.Web.Media.SmoothStreaming.dll
  • Great base classes like MergeableCollection, SimpleEventArgs and ObservableObject
  • A light weight data project
  • Logging
  • Blendability – the player is easily skinned
  • InStream markers
  • Bitrate – the ability to show bitrate

For a more detailed list of features, and the code, check out SMF’s site.

Silverlight Video Player

http://slvideoplayer.codeplex.com/

If you have ever watched a video on Channel 9 (if you haven’t check out Silverlight TV) the player being used is this video player.  It was developed by Tim Heuer (Microsoft) and Joel Nuebeck (Silverlight MVP).  Although SVP does not the feature set the SMF player has, this is still a solid and proven video player.  It’s is probably the best option for a standard, light weight, feature rich video player.

Silverlight HyperVideo player (HVP)

http://slhvp.com/

A new video player to the scene is the Silverlight Hyper-Video Player (HVP).  This offering is from Jesse Liberty (Microsoft) and the Community.  Targeting Silverlight 4, HVP takes advantage of the MEF framework and is rooted in best development practices.  Although the project is young, there is a lot of traction and Jesse is doing an amazing job of documenting each step.  Keep on eye on HVP as this maybe the most scalable offering.

Others

The above three video players I have personally used, dug through the code, and/or evaluated.  The following projects I am not as familiar with, but could be possible options for your scenario:

Sharepoint video playerhttp://svp.codeplex.com/

Silverlight Media Player http://silverlight30.codeplex.com/

xLite player http://xliteplayer.codeplex.com/