Important: This code works with the latest tip
of the Umbraco v5 code (as of 8th November 2011) and is not
guaranteed to work with alpha 3 - or any other version for that
matter! The codebase is in flux so things could change at any time.
I'll try and post back if anything becomes out of date - please use
the comments if I've missed anything! Get the code from
codeplex here.
The aim of this provider is not really to do anything useful,
but just to get to grips with what it takes to build one. I
basically took the Wordpress Hive
Provider code (also available in
the Umbraco V5 Contrib project), and updated it for my own
nefarious purposes. I've created a simple, read-only provider which
expects a SQL Server database to exist with a table called products
in it. It's simple because there are no relations in my datasource
- only products, no categories or anything like that.
Your products table should look like this:

(Yeah, I know, a product should probably have a name, but I
forgot)
Now create your own Visual Studio project which will contain the
code for your provider. You'll need to get the code
from codeplex as to go through everything here line by
line would get pretty tedious. Your code should look something like
this in Visual Studio:

All of the code has been commented as much as possible, so have
a look and see what you think.
Here, I'll go through some of the more interesting classes, and
then maybe a few gotchas about getting it all to work.
In the Entity folder, the real meat is in the Repository.cs
class - everything else is just copied from Wordpress for now (but
check out Matt's comments in the code). The only real work that
I've done in here is to implement PerformGet and PerformGetAll,
which return TypedEntity objects from the datasource.
In the Schema folder we are really defining the shape of our
data. AttributeDefinitions define your attributes, in this case
there is one for description and one for price, because these are
the attributes of my product. AttributeGroups are for organising
attributes into tabs which you'll see in the Umbraco admin. I'm
taking this on faith, because at the moment I haven't gotten that
far! Attribute types are similar to datatypes, in this case I'm
using a RichTextEditorAttributeType for the description and a
TextStringAttributeType for the price. Again, these will define how
the items look when you're editing them in the Umbraco
interface.
The ProductSchema pulls together my attributes, I'm basically
saying a product has a description and a price (again to match the
table in my database). You'll notice there is another Repository
class here, this one is for retrieving the product schema and
returns ProductSchema object(s).
Massive.cs is a "Single File Database Lover"
according to its creator Rob Conery. it's a pretty amazing 350 line
data access layer which takes care of getting the data from our
datasource.
In my Tests folder I have some basic tests which check that you
can get all products, and get an individual product, respectively.
If you are using NUnit, you just open up your dll and it'll find
them for you - it's dead simple. Note that NUnit expects an
app.config file to exist with the connectionstring in there, as it
knows nothing about the Umbraco web.config.
I hope that makes sense. Let me now say a few things about how
to get your provider into Umbraco v5.
I mentioned the connectionstring for nunit. In Umbraco v5, the
web.config files are read from the bottom up, instead of from the
top down. This means that you can override settings in the
web.config by including your own web.config with your providers,
custom trees, etc. This doesn't seem to work for connectionstrings
for Massive at the moment, so put it in the
Web.Template.config.
Important: Don't put it in the Web.config in
the root of your site because it will get overwritten by
Web.Template.config when the app recycles.
Use a post-build event on your project to copy your dll into
Umbraco. You should use something like the following file structure
(this also includes other stuff so just focus on the Providers
folder):

You can see that the dlls goes in a /lib folder and that I've
included a web.config for my Trees to add my own custom web.config
settings required for the tree (but that's for another blog post).
You could also have them all in a single dll.
So your post-build event will look something like:
XCOPY "$(ProjectDir)bin\Debug\WebGarden.Hive.Providers.Products.dll"
"$(ProjectDir)..\V5_Alpha3\Source\Web Apps\Umbraco.Cms.Web.UI\App_Plugins\WebGarden\Providers\lib" /y
In Darren's code in the
Umbraco 5 Contrib project there is a neat trick to copy a text
file into the bin folder of Umbraco to force the app to recycle,
which doesn't happen when you copy your dlls into the Packages
folder. So I've nicked this idea too which you can see in the
post-build events for the WebGarden.Trees project.
When you have all of this set up, you can test if your provider
is working by using NUnit to run your tests. I'll post further
about getting your data into a custom tree very soon.
Happy coding!
David
UPDATE: Thanks to js4xon for pointing out that I've
left out one vital piece of the puzzle. You'll also need to
configure Hive to use your provider. To do this add the following
settings to your Umbraco/Config/umbraco.hive.config file
(unfortunately deep config doesn't work for this either, hopefully
in the future you can have all your settings in a single web.config
for your package).
In your /hive/available-providers/writers section add this:
<add key="wg-products" type="WebGarden.Hive.Providers.Products.Entity.RepositoryFactory, WebGarden.Hive.Providers.Products" providerConfig="" />
And in your /hive/provider-groups section, add this:
<group key="products">
<readers>
<use provider="wg-products" ordinal="0" />
</readers>
<read-writers>
<use provider="wg-products" ordinal="0" isPassthrough="false" />
</read-writers>
<uri-matches>
<match uri="products://" />
</uri-matches>
</group>
And you're done! Have a look at my next blog post, which
describes
how to display your product data in a custom tree in Umbraco
v5.