Rants Tagged with “Open Source”
1 (Total Pages: 1/Total Results: 5)

So my blog has been pretty quiet lately and I thought I'd let you know why. With a small team, I've been building GiveAQuiz.com.
Several months ago I was working with a client who wanted me to put together a short quiz on Silverlight to help determine which of their developers got to join their Silverlight team. So I did what I always do, I searched the Internet for some small startup site that let's me accomplish the task at hand. Unfortunately all I found were logs of 'survey' sites that would let me put together some questions but only receive summary results. The one site I found that would let me build a quiz, only would let me print a PDF of the quiz to give to people by hand. This got me thinking about how a site that let people give quizzes might not only be helpful to people like me, but also to teachers of all kinds. I was determined to create the site...when I had free time (yeah, I know).
As I had chances, I would do some small part of the planning. When I wrote a SketchFlow article, I used the opportunity to prototype some of the screens for the article. But to get the site really built, I needed help. To the rescue came Microsoft and Chris Sells. Chris and I decided we wanted to build the site in the same spirit as NerdDinner.com. Microsoft would help fund the development of the site and I would write a whitepaper and do some videos on how we built the site.
I put together a small team consisting of Chris Rauber (ASP.NET MVC dev extraordinaire), Dennis Estanislao (designer savant) and myself to build this site. The site is now live, but is in a private beta mode (where you can e-mail me to get an account for a limited number of users) until we get the bugs out.
Building the site was a lot of fun and we got to mix a lot of technologies inlcuding:
From the beginning the expectation was to have the source code available under MS-PL so that it could be an exemplar for other developers to see how a site with the latest Microsoft stack. You can find the current version of the source code on CodePlex at http://giveaquiz.codeplex.com. We are accepting new members to help implement new features after launch so if you're interested in helping, feel free to apply on the CodePlex site. We we do a formal release of code once the private beta is complete. We also used AgileZen.com (who graciously granted us a free license since we were working on an open source project) and using it for workflow between disconnected members turned out really well. Love the product!
So now its your turn, I want to ask you my readers to check out GiveAQuiz.com and ask for a private beta account. The first twenty-five people who contact me at "shawn at giveaquiz dot com" will get into the private beta. Help us find the bugs please!
As some of you may know, I am a contributor to the SilverlightContrib open source project. Recently this project and the Silverlight Extensions open source project (also know as SLExtensions) decided to merge to create a single place for a lot of interesting functionality.
I want to highlight some of the pieces that I didn't contribute as I've seen a lot of really great functionality for those of you who are building Silverlight Applications. I honestly have no idea how many parts this blog series will be, as long as I have parts that are interesting, I'll continue to post about them.
First up is SLExtension's Bootstrapper functionality. If you are currently using Prism or a related technology to compose your application at runtime, this functionality is lost on you. The Bootstrapper functionality is for that middle-ground where you want to break up your project into a small number of .xap files that are loaded when the project loads up but don't need a full composition engine with MEF or Prism.
The Bootstrapper functionality is in a separately assembly in the SLExtensions project (SLExtensions.Bootstrapping.dll). This is a small assembly (so that your main project loads fast). The way it works is to have you change the derived class for the App.xaml to a BootstrapApplication:
public partial class App : BootstrapApplication
{
Since its the App.xaml class, you'll need to change the XAML as well:
<bs:BootstrapApplication
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="FunWithBootstrapper.App"
xmlns:bs="clr-namespace:SLExtensions.Bootstrapping;
assembly=SLExtensions.Bootstrapping">
<bs:BootstrapApplication.Resources>
</bs:BootstrapApplication.Resources>
</bs:BootstrapApplication>
Once you have the application changed, you will need to override the Xaps property to supply the list of XAP files to load:
protected override IEnumerable<Uri> Xaps
{
get
{
// Must be absolute Uris so we steal it from the host
return new Uri[] {
new Uri(new Uri(Host.Source.AbsoluteUri), "SecondApp.xap"),
new Uri(new Uri(Host.Source.AbsoluteUri), "ThirdApp.xap"),
};
}
}
At this point it will load up the other .xap files but we won't be able to do anything with them. So let's look at the other projects briefly.

The other Silverlight projects are actually full Silverlight Applications (not Client Library projects). The Bootstrapper is usually used to create a 'splash screen' xap file that loads the other parts of the applications. Again, not real composition like Prism, but something less than that.

In the main project, you will make a reference to the other application projects. That's how you'll be able to reference the code from the other xap files (though only once they've been loaded).
To help you know when its updated, the Bootstrapper application has two facilities:
- Progress event
- OnApplicationReady overridable method
Now that you have a bootstrapping application, you want to be able to work with it. The first thing I usually do (because I want to use the Bootstrapping API's from anywhere without casting) is create a new static property on the Application class:
// Better access to the bootstrapping app
public static App MyApp
{
get { return Current as App; }
}
Then I can use the Progress event to show the user some progress like so:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
App.MyApp.Progress +=
new EventHandler<BootstrapEventArgs>(Bootstrap_Progress);
}
void Bootstrap_Progress(object sender, BootstrapEventArgs e)
{
thePartProgress.Value = e.StepProgress;
theFullProgress.Value = e.OverallProgress;
}
I'd like to be able to know when the application is completely loaded too. Unfortunately the Progress event tends to not return 100% at any time. I haven't figured out why yet, but to get around that you can use the OnApplicationReady overridable method:
public partial class App : BootstrapApplication
{
...
protected override void OnApplicationReady(StartupEventArgs e)
{
// Do startup behavior
}
...
}
While this works, I often don't want to do this work in the App class, but instead in other parts of my application (e.g. MainForm.xaml.cs). So For my use, I usually expose an event as well:
public event EventHandler<StartupEventArgs> StartupComplete;
protected override void OnApplicationReady(StartupEventArgs e)
{
if (StartupComplete != null)
{
StartupComplete(this, e);
}
}
By throwing an event when the application is ready, I can register for this event and do the startup once I know all the code is available:
// MainPage.xaml.cs
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
App.MyApp.Progress +=
new EventHandler<BootstrapEventArgs>(Bootstrap_Progress);
App.MyApp.StartupComplete +=
new EventHandler<StartupEventArgs>(Bootstrap_StartupComplete);
}
void Bootstrap_StartupComplete(object sender, StartupEventArgs e)
{
// Use the loaded types
// (SecondApp.MainPage and ThirdApp.MainPage)
theSecondApp.Children.Add(new SecondApp.MainPage());
theThirdApp.Children.Add(new ThirdApp.MainPage());
}
Note that once the bootstrapping has completed you can use the assemblies in the other .xap projects. If you attempt to use them before, you'll get an exception that it couldn't load the type.
Just to prove the point, here is a list of the .xap files. Notice that the 2nd and 3rd .xap file are pretty big but even with the bootstrapping assembly, our code is only 10K which means it should load very fast:

Neat? What do you think?
You can get the source to my example here:
http://wildermuth.com/downloads/FunWithBootstrapper.zip
The goal of Project Niagara is to democratize the validation support. The project wants to help developers add validation support to ADO.NET Data Services as well as Web Services in Silverlight. In addition, it has the goal of allowing multiple ways to supply the validation metadata to the different data access strategies. As it is my opinion that there are scenarios where attributes are not the best idea.
The deliverables for this project will include:
- ValidatingDataSvcUtil: Produce Validating Data Service Proxies.
- ValidatingProxy Library: Supply external metadata for generation of Proxies.
- MValidation: DSL for defining Validation outside of attributes.
- Oslo Integration: to store/retrieve validation out of the Oslo Repository.
- Alignment: RIA Services' and ADO.NET Data Services' Validation Logic
At this point the project is very young (version 0.1) and a lot of the pieces are not ready but I am looking for help! I can't write it all. Please visit the CodePlex site and take a look at what I want to accomplish and send me a message if you want to help out:
http://niagara.codeplex.com
Current State of Niagara
Currently, I have built up some infrastructure to allow the whole project. This inlcudes a first pass at the DSL. The one working pieces is the ValidatingDataServiceUtil which allows you to manually generate (via the command-line) an ADO.NET Data Service proxy that includes support for validation attributes and calling validation during two-way binding.
The current version does not have a release yet, but if you're brave and willing to report bugs, you can get the source and build it yourself.
To use the ValidatingDataServiceUtil, you can call it from the command-line:
NiagaraDataServiceUtil.exe http://localhost:14000/GameService.svc
..\Niagara.Sample.Web\bin\Niagara.Sample.Web.dll
.\GameService.cs
Niagara.Sample.Data /v /b /c:V2
While more complex than the original DataSvcUtil, the arguments are pretty straightforward:
- URI to the ADO.NET Data Service endpoint.
- Path to the assembly that holds the types and metadata (so we can read the metadata with reflection).
- The output file.
- The namespace to use.
- Options to specify what version of the data service library to use, bindability and validation.
This is an alternative to using a service reference. We hope to move this to be a project item instead of a command-line for the project.
NOTE: It requires the ADO.NET Data Services CTP2 to work.
Let me know what you think!
If you haven't read Part 1 yet, you can read it here.
After spending time creating my own caches of reflection data I found the NHibernate type information to be more complete and faster. Go figure. At this point I am using the SessionFactory's GetClassMetadata and GetCollectionMetadata to return IClassMetadata and ICollectionMetadata interfaces. So far this has given me every piece of runtime information I need and means that I don't need to do any nasty (and potentially fragile) walking through the property interface of the context object. Whew...
So to refactor my GetResource and CreateResource calls. GetResource is easy. GetResource passes in the query and the full type name (though the full type name may be missing in some cases). The query it passes it must resolve to a single result. That means I can simply execute the the query and if it returns more or less than one result, return an error. Once I have the result I can just check it against the full type name (if it was passed in) and return the value.
CreateResource is a bit more complicated. The IClassMetadata allows me to call their Instantiate method to create a new instance of the class but the new instance is not initialized with any data. Most notably, the missing detail is a key. In the case of many entities, this is fine (e.g. if zero ID is a valid "new" entity). But in others the key needs to be specified. (Customer in the Northwind database is an example of this.) The problem is that we have to keep a reference to the new objects so that when ADO.NET Data Services asks us to set properties, get properties and save, we have to have the object in the Session. But we can't add it to the Session with an invalid key. What to do? My solution for now is a local cache of objects that are not ready to be saved (only really happens with newly created objects). When we are ready to save, we'll just add it to the Session then (when its either valid or we'll throw an exception because its invalid).
Now a quick mention of GetProperty and SetProperty. These are both pretty easy as the IClassMetadata includes a similar method to set and get properties. The only wrinkle is that if you try and set a key using the GetProperty/SetProperty, the keys are not in the list of properties. Because of this I just checked to see if the property is part of the key and set the key instead, if its not part of the key we can just set or get the property. Now that we have the basic part of the interface complete its down to the hard parts. But that's for the next part!
I have been diving pretty deep into ADO.NET Data Services (see an upcoming article about ADO.NET Data Services and Silverlight 2 coming soon). I've been looking at the story around non-Entity Framework models through a Data Service and thought that NHibernate through a Data Service would be a great example.
So I tried to get it to work with the NHibernate LINQ project. The example model that the project uses is a simple Northwind model. I thought I'd just take that model and expose it via ADO.NET Data Services. I crufted up a simple Data Context object for ADO.NET Data Model but it didn't work. ADO.NET Data Services was complaining about the fact that the end-points (e.g. IQueryable<Customer>) was pointing at an Entity. This was a bug...a but in ADO.NET Data Services. I hacked together a fix to get around it (and reporting it). If you're interest, the problem is that if the key of the entity is in a base class and *not* named "ID", it fails to find it. Again, this is a bug not a feature of ADO.NET Data Services.
Now that it was working, now what? I wanted to be able to make changes to the model but the NHibernate context doesn't support the updating interface: IUpdatable. (Though I sure wish they'd rename it IUpdateProvider to match the IExpandProvider interface). If you're not familiar with this requirement, note that only the Entity Framework currently support the IUpdatable interface (and is in fact implemented inside of ADO.NET Data Services not directly in Entity Framework). This means that DataSets and LINQ to SQL do not support it either.
That's where I went to the Rhino Google Group (the discussion point for this project) and offered to implement the IUpdatable for the NHibernate provider. I thought it would be a fun exercise to understand the guts of the ADO.NET Data Service stack.
My first chore was to attempt to find a solution to decouple System.Data.Services.dll from the rest of the LINQ provider. My reasoning for this is that ADO.NET Data Services requires .NET 3.5 SP1 and I didn't want to tie the changes to that version of the Framework. Interestingly this is the same tactic that the ADO.NET Data Services team took. This is why the Entity Framework does not implement the IUpdatable interface themselves, but the ADO.NET Data Service does it for them. For the rest of the world, it expects a IUpdatable implementation directly on the context object that is used as the starting point for the service. After running around a number of ideas and running it by the Rhino people, we've decided to table that problem and get the interface working. That will be a fight we fight later with a number of proposed solutions.
So now that architecture is out of the way, its time to start actually implementing the interface. For the first pass, I am going to implement IUpdatable directly on NHibernateContext and refactor it later for less tight coupling. While I am at it, I also want to add support for IExpandProvider so that we can do expansions through NHibernate.
After adding the interface to the context object, I looked through the interface (its about a dozen calls that need to be implemented) to determine where to start. I am starting with the simple calls (GetResource, CreateResource, DeleteResource). These calls are used by the service to do basic object manipulation.
For GetResource, I am handed a query and possibly a type name. GetResource is supposed to invoke the query to get the one and only one result (implementors should throw an error if the result returns more than one result) and then check the type name against the result. In some cases you won't get the type name, but in most cases you will need to verify that the type of the result is the same as the type name. This is used to make sure that derived types are correctly retrieved from the data provider.
In implementing CreateResource, I noticed that I needed to be able to look up type information. Type information is important as I need information about the containers (e.g. IQueryable endpoints) on the context object. This information is not readily available as its the classes that derive from NHibernate that add these end-points. I could get the type information via NHibernate's type information or using Reflection (neither are particularly cheap). For the first iteration I choose Reflection since I know that better, but I wanted to mitigate the cost with some caching. To that end, I've created some small in-memory caches of the reflection information that hopefully will help with the performance of these lookups. This type information will help act like a factory to create new instances of the object. Unlike other ORM's, NHibernate doesn't use factories but uses simple object creation so we can just use the reflection information to create the instance of the new object and attach it to the NHibernate ISession.
Lastly, the simplest of the three methods to implement is the DeleteResource as it passes in a query (again, should always only return a single result) and mark it deleted in the session. The change shouldn't be persisted (there is a SaveChanges call on the IQueryable interface that facilities the actual persistence to the data store).
Overall a fun couple of days. Now on to the rest of the interface. I'll keep you posted with my experience dealing with them!