Lazy Loading an Observable Array with Knockout JS
I recently had the need to lazy load a list of items using Knockout JS. Luckily, this problem has already been solved…mostly. I suggest you go read that post for the concept behind how lazy loading with Knockout works in general.
The part that was missing from that implementation for me was the Knockout array methods that are usually on an observableArray. E.g., when you do this using the code from the aforementioned post:
this.lazyItems = ko.lazyObservable(function() {
$.post("/get/some/json", function(data) {
//where data is an array of items
this.lazyItems(data);
});
}, this);
//...... somewhere else far away ......
this.lazyItems.push(myNewItem);
You will get an error saying push is undefined on your lazy observable. The problem lies in the fact that ko.lazyObservable is returning a computed observable that wraps another observable with some lazy loading behavior. The computed observable that is returned has none of the knockout methods for manipulating arrays. Even if we simply update the inner value to be an observableArray rather than a plain observable within the lazyObservable, we are still never exposing that object. It is safely tucked away as a private variable in our lazyObservable.
To make a long story short, I ended up adding another lazy method, lazyObservableArray which exposes all of the underlying knockout methods for manipulating arrays.
ko.lazyObservableArray = function (callback, context) {
var value = ko.observableArray();
var result = lazyComputed(callback, value, context);
//add underlying array methods onto computed observable
ko.utils.arrayForEach(["remove", "removeAll", "destroy", "destroyAll", "indexOf", "replace", "pop", "push", "reverse", "shift", "sort", "splice", "unshift", "slice"], function (methodName) {
result[methodName] = function () {
value[methodName].apply(value, arguments);
};
});
return result;
};
That technique for delegating calls to an underlying object I stole directly from the knockout source code since that is how it does some of its magic with observableArray methods.
Using this new method, we can now run our previous code with a lazyObservableArray and happily push, pop, remove or do whatever we want to our array without fear of undefined functions.
See here for a gist containing the full source code. Note: the define call in the beginning of the file is a requireJS module definition (in case you have not seen this before). Fear it not.
What you get with Git
I recently broke down and decided to try and use Git for something. Practically every open source project I use has now moved to GitHub and it was becoming hard to submit patches (or pull requests or whatever) without having a Git client on my machine.
I decided to install GitHub for Windows since it is new and it is the thing I have most recently heard about. I was very pleased with my initial impressions with it – very nice UI and workflow. The two features I immediately found lacking were the lack of being able to define an external diff/conflict viewer and the inability to show a log on a particular file. However, I’m looking forward to future versions which I am sure things like that will be addressed. Besides for now, if the project is hosted on GitHub, it is easy enough to click the “view on github” link and see the history info there.
Git, coming from an SVN background, does take some getting used to. Branches and tags are different, file renames and deletes are much easier in that you don’t really need to track it – git does it for you automagically (which was confusing at first for me). Overall, though, it makes a lot more sense for open source projects as far as sharing code and collaborating with many disparate parties.
Anyway, long story short, I liked it so much that I ended moving my two, lonely open source projects over to GitHub. They can now be found here:
I also took this opportunity to finally finish v2.0 of Geocoding.Net since I have neglected it for a good while now. It fixes a bunch of bugs people have logged with it and it also adds reverse geocoding support.
It was relatively painless migrating the repos from svn to git while still preserving commit history. And now that is done, I am enjoying the disconnected commit model you get with git especially since Isaac is coming to disconnect my internet and power very soon.
Creating NHibernate Linq Query from arbitrary Criteria
I just added this gem to NHibernate.Linq (of the NHContrib variety – not to be confused with that other one). I’ll let the test speak for itself:
[Test]
public void can_create_linq_query_from_arbitrary_criteria_query()
{
var criteria = session.CreateCriteria<User>();
criteria.Add(Restrictions.Le("RegisteredAt", new DateTime(2000, 1, 1)));
var query = session.Linq<User>(criteria)
.Where(u => u.Name == "nhibernate" || u.Name == "ayende");
var list = query.ToList();
Assert.AreEqual(1, list.Count);
Assert.AreEqual("nhibernate", list.Single().Name);
}
My specific reason for adding this has to do with a custom ICriterion (more on that later) I needed to use in one of our criteria queries that I wanted to expose as an IQueryable. This method of being able to build a linq query from an arbitrary criteria seemed to solve my problem rather elegantly.
Let me know if you think this is crazy or if you like.
As of now, it is available in the trunk r1099.
The Many Pitfalls of NHibernate.Linq
Working with the recently released NHibernate.Linq is not without its (many) pitfalls. In one of my current projects, we are using the specification pattern to build dynamic linq queries based off of persistable specification objects. This has led to more than one hair-pulling session on the limitations of the current NH Linq provider. For instance, did you know that this query will work just fine:
(from p in db.Patients from r in p.PatientRecords where r.Type.TypeCode == 7 select r).Sum(r => r.Amount);
yet, this query (which is equivalent) will blow up in your face:
db.Patients.SelectMany(p => p.PatientRecords)
.Where(r => r.Type.TypeCode == 7).Sum(r => r.Amount);
The reason it fails is very implementation-specific. Under the covers, the C# compiler will convert that first query into an expression looking something like this:
db.Patients.SelectMany(p => p.PatientRecords, (p, r) => new { p = p, r = r })
.Where(pr => pr.r.Type.TypeCode == 7).Sum(pr => pr.r.Amount);
Our second query which uses the overload of SelectMany that doesn’t specify the result selector fails because NHibernate.Linq specifically requires that result selector in order to know which alias to use for that subcriteria for the rest of the query (yes, this is a really bad implementation and requires that you use the same lambda parameter names throughout your query).
Simple enough, let’s just drive around the pothole and explicitly state our parameter name by changing our second query to look like this:
db.Patients.SelectMany(p => p.PatientRecords, (p, r) => r)
.Where(r => r.Type.TypeCode == 7).Sum(r => r.Amount);
Ahh,explosions still abound. That query will generate an error similar to: “Type is not an association” or “Could not resolve property: Type”.
It turns out,that NHibernate.Linq’s SelectMany support depends on that anonymous type leading the entity types in the query (pr.r in the compiled first query). Without this leading anonymous type, the parser does not assign a subcriteria to that many-to-one traversal through r.Type. That is highly upsetting because the query that we are writing is actually more like this:
db.Patients.SelectMany(p => p.PatientRecords, (p, r) => r)
.Where(specification.IsSatisfied()).Sum(r => r.Amount);
where specification.IsSatisfied() returns a dynamically generated Expression<Func<PatientRecord, bool>>. I can’t rewrite those specifications to use some query-specific anonymous type and I shouldn’t have to.
On a mission, I fired up the NHibernate.Linq source code and hacked away at it until this specific scenario was supported. There is still the limitation that you must use the second overload of SelectMany that accepts the result selector. There is no way of easily getting around that with the current implementation based off of the Criteria API. However, despite all of NHibernate.Linq’s shortcomings, my specifications now work just fine (running some pretty complex queries).
If you are having similar frustrations, go grab the latest trunk r1010.
…until the next bug
P.S. I am very much looking forward to NH.Linq 2.0 using relinq and the new AST parser.
NHibernate.Linq 1.0 is out and about!
In case you haven’t heard, NHibernate.Linq v1.0 has been released. This has been a long time in the making and Tuna has put the final touches on it to make it possible. You can get the binaries from the NHibernate download area.
Here are some informal release notes:
The implementation uses the NHibernate Criteria API under the covers, so anything it doesn’t support, NH.Linq won’t support. Other things were just too hard to implement using the Criteria API. Some major things this includes are group joins, subqueries in select clauses, and groupby.
However, despite that, limited subqueries are supported in the where clause. Namely, using Count, Sum, Max, Min,Avg,and Any methods. You can also use SelectMany queries (rather than GroupJoin) to do queries like this:
from o in db.Orders from ol in o.LineItems where ol.Price > 10 select o;
or this:
from o in db.Orders where o.LineItems.Any(ol => ol.Price > 10) select o;
All in all, it is a tried and tested implementation. It has been used on number of projects in production for two years now. As long as you know where the pitfalls are and how to avoid them, it is a useful addition to your NH toolkit.
Now, if you are saying to yourself, “well, that sucks, I really wanted to use GroupJoin and I want to nest other queries in my select clause.” Fear not, this is where Steve Strong and the re-linq guys come in to save the day. Steve has done a lot of all of the work on porting over the current HQL parser that is active in NHibernate 2.1. The new linq implementation will interact with it natively (rather than use the Criteria API as an intermediary). The current implementation has pretty much reached its upper limit on what it can do – limited by what the Criteria API can do. The new implementation has much more grandiose plans than the current release. It is the future, but, as most of us live in the present, this release is now.
For all intents and purposes, consider this a stopgap release. Again, that doesn’t mean its not capable – just don’t expect major new features from this implementation.
Thanks to Tuna and Oren for pushing this release out the door.
We make shitty software (and so do you!)
I just ran across this little gem and it made me laugh:
An old software slogan at Living Videotext: "We Make Shitty Software... With Bugs!" It makes me laugh! We never ran this slogan in an ad. People wouldn''t understand. But it''s the truth. We make shitty software. And so do you!
Software is a process, it''s never finished, it''s always evolving. That''s its nature. We know our software sucks. But it''s shipping! Next time we''ll do better, but even then it will be shitty. The only software that''s perfect is one you''re dreaming about. Real software crashes, loses data, is hard to learn and hard to use. But it''s a process. We''ll make it less shitty. Just watch!
Talking with an unhappy customer, first validate their belief that you''ve let them down. I agree that our software isn''t perfect. You won''t get an argument here. Let''s move on, find a workaround, a way to get your data back. And we promise to take a look at this problem and, if possible, fix it in the next release.
And that is back from 1995. Wow, I was only 10 years old back then…
Dependency Injection with NHibernate and Autofac
Fabio just recently committed changes to NHibernate which centralize all of NHibernate’s Activator.CreateInstance calls to an IObjectsFactory instance. This is exciting because this gives us an opportunity to provide dependency injection services to all of those NHibernate-specific infrastructure types (IUserType, etc.).
To give you a concrete example of what I am talking about, check back to Ayende’s EncryptedStringUserType. Rather than getting an instance of ICryptoProvider via a singleton accessor, it is now possible to have NHibernate inject the ICryptoProvider dependency through the constructor. This is very valuable in cases where the ICryptoProvider has other dependencies or has some parameters that need to come from configuration. You get full support from the container for that.
Fabio wrote up a post describing the implementations for Castle and Spring. So, I thought I’d follow suit with an implementation for my new favorite container, Autofac (why it is my new favorite container will be a topic for another post).
To use it, make sure you are using the latest trunk of NHibernate. Then, just add a reference in your project to Autofac.Integration.NHibernate. At this time, the only way to configure the BytecodeProvider is programmatically. So, BEFORE you call new NHibernate.Cfg.Configuration().Configure(), you need to set the BytecodeProvider to the AutofacBytecodeProvider.
containerProvider = new ContainerProvider(builder.Build());
Environment.BytecodeProvider = new AutofacBytecodeProvider(
containerProvider.ApplicationContainer, new ProxyFactoryFactory());
Then just enjoy the DI goodness integrated with NH. If any type NHibernate needs is not registered with the container,it will fall back to creating the type with Activator.CreateInstance.
The code can be found here. I am going to contact the Autofac guys and see about putting this into the Autofac.Contrib project.
Update: This is now included in the Autofac.Contrib project – check it out here.
BDD with xUnit.net
I’ve been looking a lot into Behavior Driven Development lately as a better way to structure my TDD tests. If you’ve never heard of BDD, check here for an intro (or here for another good one). What it boils down to is a way to organize and name your tests in a way that makes it explicit what it is – an executable specification for what the code under test should do.
One particular quote that stood out in my mind when getting to know BDD was this:
Language you use shapes how you think... and if you want to change how you think it can help to first change your language.
It is true in that just changing seemingly insignificant things like the language and syntax of your tests can affect how you think about your tests and ultimately how and what tests you end up writing.
I set out to find a solution to help me start writing BDD-style tests (ehh, I mean specs) in an existing project which already used xUnit.net. I really liked some of the things from SpecUnit, but I didn’t want to be tied to NUnit. I also found the xUnit BDD Extensions project on Google Code – but I took issue with some of the syntax with that. Also, it seemed to be trying to do too much. I just wanted simple BDD style integration with xUnit without any excess baggage.
One of the things I really like about xUnit (and the reason why I use it over MBUnit and NUnit) is its simplicity. It is clean, elegant, and efficient at what it does. It provides exactly what you need and nothing more. It also makes use of native C# semantics for its syntax. For instance, rather than relying on a TestSetup or TestTearDown attribute for a setup method to a test, it relies on C# constructors and the IDisposable interface to handle such things. When writing test cases with this syntax, it feels much more natural.
Anyway, I ended up finding this BDD solution for xUnit by Fredrik Kalseth. This was almost exactly what I was looking for, except that I didn’t like having to override InitializeContext in my spec classes. I wanted to include the context in the constructor of the class like normal xUnit test classes.
Also,some of my current test code relies on test base classes for some of its functionality – and I didn’t want to force my tests to inherit from a Specification class just to get BDD style testing done.
Last but not least,up until the latest 1.1 release of xUnit, the xunit.extensions assembly contained these nice .Net 3.5 extension methods for assertions in a very BDD style way. It allowed you to write code like this:
customer.Email.ShouldEqual("test@example.com");
With the latest release, however, these extension methods were deemed unworthy and moved to the xUnit Samples project. Boo I say to you. I want, neigh, need these extension methods back.
Long story short, I ended up taking elements from all three of these solutions along with the extension methods from the samples project and created my own. I present to you Chad’s version of xUnit BDD Extensions.
Some of the design goals of this project:
- Use natural C# constructs to control things such as BDD contexts and concerns. For example, the context of the specification is defined in the class constructor and the concern for the fixture is defined by its namespace.
- Don’t force me to inherit from any base class to get BDD style tests working. There is an interface ISpecification with one method Observe() to accomplish this. A Specification base class is also provided for convenience.
For completeness, I am including the cliché BDD example of an account transfer fixture using this framework.
namespace Banking.Specs.FundsTransferSpecs
{
public abstract class behaves_like_bank_account_transfer : Specification
{
protected readonly Account fromAccount;
protected readonly Account toAccount;
public behaves_like_bank_account_transfer()
{
fromAccount = new Account { Balance = 1m };
toAccount = new Account { Balance = 1m };
}
}
public class when_transferring_between_two_accounts
: behaves_like_bank_account_transfer
{
protected override void Observe()
{
fromAccount.Transfer(1m, toAccount);
}
[Observation]
public void should_debit_the_from_account_by_the_amount_transferred()
{
fromAccount.Balance.ShouldEqual(0m);
}
[Observation]
public void should_credit_the_to_account_by_the_amount_transferred()
{
toAccount.Balance.ShouldEqual(2m);
}
}
public class when_transfering_amount_greater_than_balance_of_from_account
: behaves_like_bank_account_transfer
{
private Exception exception;
protected override void Observe()
{
exception = ((MethodThatThrows)delegate
{
fromAccount.Transfer(2m, toAccount);
})
.GetException();
}
[Observation]
public void should_not_allow_the_transfer()
{
exception.ShouldNotBeNull();
}
[Observation]
public void should_raise_argument_out_of_range_exception()
{
exception.ShouldBeType<ArgumentOutOfRangeException>();
}
}
}
namespace Banking
{
public class Account
{
public decimal Balance { get; set; }
public void Transfer(decimal amount, Account toAccount)
{
if (amount > Balance)
{
throw new ArgumentOutOfRangeException("amount", amount,
String.Format(@"Cannot transfer ${0}.
The available balance is ${1}.", amount, Balance));
}
Balance -= amount;
toAccount.Balance += amount;
}
}
}
Note the use of the namespace Banking.Specs.FundsTransferSpecs to denote the current concern – funds transfer. Also note the use of how easily it is to reuse context setup code via constructor overrides. Its nothing new as far as BDD goes, it just puts a nicer xUnit-style syntax on it.
It is a very simple project. All credit goes to the authors of the previous three solutions. I just cobbled together the best (at least what I think is the best) of those solutions.
The code for this (in cased you missed it before) can be found on the BDD Extensions project on Google Code.
Tortoise SVN Settings for Beyond Compare 3
This is for future reference for me – for some reason this is a huge pain in the ass for me to find whenever I need it.
Here is the official documentation on how to integrate BC3 with TortoiseSVN.
Here are my settings (on 64 bit machine):
Diff Viewer
"C:Program Files (x86)Beyond Compare 3BComp.exe" %base %mine /title1=%bname /title2=%yname /leftreadonly
Put the SAME THING for both “comparing different revisions of files” and “comparing different revisions of properties”.
Merge Tool
"C:Program Files (x86)Beyond Compare 3BComp.exe" %mine %theirs %base %merged /title1=%yname /title2=%tname /title3=%bname /title4=%mname
Developing with Passion
I was going through my feed reader today catching up on some of the blogs I read and I came across this post from Casey Charlton. I was pretty astonished when I read it – this coming from Mr. DDD. Not only that, but this is the second reference I’ve seen to software developers not being happy with software development in the past few days.
It got me to thinking of how I feel about this whole software thing. I’ve been on a few interviews recently and one comment that I received a few times that stuck out in my head was “you are obviously very passionate about what you do.” Hmm, does it really show that much? :,,)
I remember at one point in my life, I was dead-set on becoming an astronaut. I was going to go to Embry-Riddle for a degree in Aerospace Engineering – then I was going to join the Air Force and eventually become an astronaut and go out and fly in space. Ahh, I’m not really sure what happened to those plans.
I ended up going to LSU instead (mostly because I think I was too afraid of moving away from home) and I ended up majoring in Computer Engineering. I remember the reason I gave for picking Computer Engineering was that I was good at working with computers and I knew I definitely did not want to do something with software – I wanted to work with hardware. Ha!
At some point in college (near the beginning), I eventually found the need for money. I wanted to buy things and most people accepted money for the things I wanted. I didn’t want to get a job – who the hell wants to do work? I eventually found that people would pay me to build websites for them. After all, I dabbled in HTML and Flash back then and enjoyed building little websites. This eventually lead to me learning PHP and later on .Net.
So I guess you could say I “fell into” the field. But, really, who hasn’t “fallen” into whatever they are doing now? Who says when they are a little kid “I want to write software when I grow up” or “I want to be an investment banker” or “I want to be a construction manager”? No, you usually want to be a police man, or a fireman, or a doctor, or maybe even an astronaut when you are a kid. When it comes down to it, we all just do what we are good at.
I still feel like I could be a million different things. I used to love making little home videos (still do actually) – I could have worked somewhere in the movie industry. I definitely had the test scores and brains to be a doctor. I could have been a brain surgeon. I might have even joined the Air Force and flew a fighter jet. But I didn’t do any of those things, I wrote some software instead.
Bottom line is that I don’t see myself as a Software Developer. I spend most of my time writing software, but I still feed my interests for other things with my hobbies. I enjoy what I do and I am good at it. And some people even pay me to do what I enjoy doing. What more can somebody ask for?