Update
So I got the csinc site switched over to using v3 api instead of the v2 CloudDB strongly typed service. Generally, I like it because it allows greater flexibility. That could have been true for v2 api, but I haven’t tried it so I can’t say. The CloudDB hasn’t put together the docs for this yet, so I’ll show you some code to use it below.
Why use it
First, it keeps the website portable. It doesn’t matter where it’s hosted because the datastore doesn’t change. Second, We can tweak content and even some behavior/layout stuff easily by making the change using the clouddb website.
Implementation
I’m not entirely settled with our implementation so far. How we read columns and set object properties needs work. Also, I re-factored the base to pass in a context object basically just to pass around a pointer to the IWindsorContainer instance so it would work in the web app and in the test project. It’s one of those quick hacks which you’re not quite happy with but don’t really have another good idea at the time. I just wanted my tests to pass.
Getting started
First you have to get an invite, and then set up a clouddb account. Once done, add the clouddb api url as a webreference and begin coding. Start with the login code:
1: public static Token Login(string user, string password)
2: {
3: using (CloudDB cdb = new CloudDB())
4: {
5: return Login(cdb, user, password);
6: }
7: }
8:
9: public static Token Login(CloudDB cdb, string user, string password)
10: {
11: Token tok = cdb.LogIn(user, password).Result;
12: return tok;
13: }
Using an instance of CloudDB and the Token, you call whatever api method you need. Our site only uses reads so far. So here’s how we get a list of rows:
1: public static RowsResponseData GetRowData(CloudDB cdb, Token token, string appName, string entityName, Predicate[] predicates)
2: {
3: App app = cdb.GetApplicationByName(token, token.UserID, appName, false, false).Result;
4: Entity e = cdb.GetEntityByName(token, app, entityName, false).Result;
5: RowsResponseData rowData = cdb.SearchEntity(token, app, e, predicates, 0, 0, 0, 0).Results;
6: return rowData;
7: }
In the above code, the Predicate array is used to specify which rows to get back from clouddb. That’s how we get a single match if we want. Just query for the id or other unique criteria. Here’s how we handle that in our record base class:
1: public static T GetRecord(IAppContext context, string cacheKey, string entityName, Predicate[] predicates)
2: {
3: CachedItem ci = DataCache.GetItem(cacheKey);
4: if (ci != null) return (T)ci.Data;
5:
6: try
7: {
8: ICloudConnectionSettings connectionSettings = context.Container.Resolve<ICloudConnectionSettings>();
9: RowsResponseData rowData = CloudDBDataAccess.GetRowData(connectionSettings.CloudDBApplicationName, entityName, connectionSettings.CloudDBUser, connectionSettings.CloudDBPassword, predicates);
10: T item = new T();
11: item.Init(rowData.Data, 0);
12: DataCache.Add(cacheKey, item);
13: return item;
14: }
15: catch (Exception er)
16: {
17: T item = default(T);
18: DataCache.Add(cacheKey, item);
19: return item;
20: }
21: }
You’ll notice that caching is also handled at that layer so the specific model doesn’t have to know or think about it. (Yes, there are things I can do to improve this. Remember, time for our own site isn’t a high priority versus time for clients.)
..and a sample usage:
1: protected bool ShowDynamicContent()
2: {
3: return ShowDynamicContent(Request.FilePath.ToLower());
4: }
5:
6: protected bool ShowDynamicContent(string contentName)
7: {
8: var pageContent = PageContent.GetByPath(new AppContext(), contentName);
9: if (pageContent != null && pageContent.IsPublished)
10: {
11: PropertyBag["contentTitle"] = pageContent.Title;
12: PropertyBag["contentDescription"] = pageContent.Description;
13: PropertyBag["content"] = pageContent.Content;
14: RenderView("../shared/contentview");
15: return true;
16: }
17: return false;
18: }
1: public void Index()
2: {
3: //show dynamic content if available, defaults to view file content if not
4: ShowDynamicContent();
5: }
Good to know
Clouddb data is described with Entity objects representing the table, Column objects describing the columns for data, and Row objects containing the data. Think of it a little like a DataSet in .Net. You’ll need to know a little about the columns in the data, and then read the values from the Rows array. Also, you’'ll need to know the application name, which is the specific clouddb database in your account.
That’s a simple overview. Hopefully it helps. There is more to it, but that should get you started.


I’m continuing to play with CloudDB as the data store for the computerist solutions site. Currently the sidebar links are stored in clouddb, as well as optionally storing most page content in it. Currently, only the home page has its content in clouddb. It’s built so most pages check on first load if content is available in clouddb, otherwise render the normal view.
So all this makes me think.. why not add a users table and go full on CMS with it. I think it would work. So why not also build our own blog engine too. Again, it might just work but it becomes a question of size restrictions. I just don’t know what clouddb will allow/handle. I’ll have to ask the team about it.
Speaking of features, CloudDB is working on the next version. It may get released by the time this gets published. I’m waiting to see what changes there are. There will be JSON support I’m told, which will make be wonder whether to stick with the current webservice method of calling it or move to the JSON method.
Overall, I like clouddb. It’s perfect for the csinc site. It maintains the portability directive because we can host anywhere and still fetch data from clouddb. Plus we have some nice flexibility with the content. It really is an enticing solutions. It took some thinking to centralize the data access and caching, but worked out. Now I’m just waiting to see what clouddb v3 brings.
I’ll probably post again on CloudDB when the next version comes out. I’ll do some code samples at that time. Maybe a working sample project for people to try.
Other Goings On
In other news, I recently found myself considering buying a new vacuum. It was a good vacuum when we bought it but it had lost its power over the last year. Thanks to some random review, I rechecked the filter I thought I cleaned and found that it was actually just the housing for the actual filer. After cleaning it, the power is back! How many times have you felt you code base is old and worn out? Maybe you just need clean it out a bit instead of throwing it away. Add some tests, maybe use clouddb, or refactor some common code. Having made the clouddb changes to csinc, it feels refreshed and not so stale. I still want some more clean up and better testing but I like where its going. ..just a little life lesson applied to work.
CloudDb is a web based data store, and it’s pretty cool. I got an invite a while ago from my friend Scott Cate (mykb), but didn’t really dig too much into it. Now if you follow this blog, you’d now we’ve been looking at different data storage options for various things such as content for this site. Most embedded db’s aren’t an option because it’s currently hosted in a Medium Trust environment which doesn’t allow native calls (all the embedded db’s I know require this). That pretty much killed it. We have the option of using mysql or 1 sql server database but we’d like to keep this as portable as possible. Also, there are other plans for that.
But Hey! Why not use a cloud or web based service? We want to be able to manage some content without re-deploying, and a cloud service would allow that. Yes, most of the current content are just stored in view files, but what’s the fun in that?
I’ll probably post more info when I get something together. In the meantime, click the link and watch the videos.
I’ve been working on overcoming my own ignorance in using precompiled views with Spark view engine. Making progress, but it’s not been straight forward. It’s not really a problem with Spark, which is why I’m still trying to make it work. It’s just that errors encountered during the post build step to precompile the views aren’t clear. It required using System.Diagnostics.Debugger.Launch() to figure out the problem. Which of course was something stupid I did; put a namespace in the assemblies config section for spark.
So figured that out, and it compiled. Yay! Then I ran it..
It’s probably something else I forgot to do or whatever. Maybe I need to register routes so it knows which views to render. This is why I haven’t yet posted another Spark article. It’s suppose to cover lessons learned with precompiling view. So I should have plenty to cover.
I’m in the crunch zone for a project so posting has been infrequent. In lieu, please read up on SubSonic 3, which was just released. I have plans to use it in something I’ve had cooking for a while now, and is going to get re-made.
Also, Nate Kohari is officially awesome. Congrats.
-j
We’ve update the blog to v1.5.1.x in hopes that the future post problem is resolved in the current Trunk of the BlogEngine.Net source code. This also means we built it from source; hence the .x in the version number. Hopefully this post will show up on time which means we accomplished our goal.
The previous version had a problem with future posts not showing up at the selected time; at least in conjunction with Live Writer. That and some bug fixes should be the only changes.
-j
I'm going to move forward with the theme change for this blog in the next few days or week. There will be a couple of drawbacks. Some posts may appear odd with bad font or styles. This is a result of how I originally composed them, and, in some cases, the extensions that were used to render some content.
I'm going to start composing with Windows Live Writer, which will help with all the above issues. I will update older posts using Live Writer which have glaring problems, but feel free to bring any that I miss to our attention.
I'm moving forward with the theme change because it is an improvement on the overall site and gives the blog a more integrated feel. This is an important part of user experience with any application. It represents Computerist Solutions better to apply the same principle on our site as with our products. As with any of our products, please send feedback and let us know of any problems.
Thanks,
-j
I've found a way to get a little extra time each day by chewing my food fewer times. Do you realize how much time you waste by chewing? I've cut the number of times I chew in half. Aside from the occasional choking nearly to death, it's worked great. I have loads of extra seconds everyday!
One thing I've been doing with all that extra time is making a custom theme for this blog to match the main site. It's not done, but I would appreciate early feed back. Please compare the main side to the blog preview.
-j
So I mentioned on Twitter that I was reading Ayende's DSL with Boo book, and I recommend it. I thought it fair to mention what I'm reading now that I've finished it. Without looking at the picture to the left, can anyone guess? Hint: It's related to the work I'm currently doing with an existing application. Yeah, you guessed it. Brownfield Application Development in .Net by Kyle Baley and Don Belcham. How'd you know? I'm really busy so I'm not making quick progress; even my leisure reading is on hold.
I'm not sure, but I'm guessing that one or both of the authors have worked with or trained with JP Boodhoo because he's already been mentioned. I like that it's putting together a reasonable argument why Brownfield isn't that bad. Even lays outs some reasons why its actually a good situation. The first chapter is free so you can sample it yourself. Also, Manning emails coupons all the time so let me know if you're thinking of buying.
-j
This isn't part of the 'for humans" series; it's just an observation from my current work. I'm in the middle of some brownfield development (enhancing or adding to a program that already exists and is actively developed). So the application I'm working with doesn't really support unit testing. All the pieces are too tightly tied together, but we are working on it as we go. For example, I just added some code that looks a little like this:
[code:c#]
public interface IState
{
bool IsConfigured {get;}
void ClearState();
}
[/code]
Using this interface I can test some of the code that uses it. It's nice because my unit tests tell me if it works and I don't have to run the whole app. Plus I get the benefit of being able to work on whatever part I want to: middle layer, UI, data layer. It's nice to be free.
However, I have to write lots of code that goes right into the rest of the app that I can't test easily. Something like this:
[code:c#]
public class Import
{
void ImportStuff ()
{
IState state = GetTheCurrentState();
if(state.IsConfigured) RunImport();
}
}
[/code]
With that I have to start the whole app and test it manually, which also means I have to build some rudimentary UI to execute that code. This is called top-down design when you are basically writing UI and top level features before writing middle layer, business rules, and data layer code. It doesn't lend itself to a good design and maintainability. For whatever reason, it just occured to me that developing that way tends to force you into it, which also leads to more pain points in the application.
Test Driven Design definitely has the advantage here. More Freedom, more fun, better code. Trust me.
-j