Home » Blog

rounded header

Archive for November, 2007

Summer of Code

tag icon Tagged as Events, General

My name is Mathew Campbell-Adams. I’m a student at Vic, studying towards a BSc in Computer Science and Maths, and an LLB; I’ve just finished my third year, and because of my degree choice, I’ve got at least another two to go.

Summer of Code and Me

The Summer of Code internship programme (unrelated to the Google Summer of Code internship programme) began last year to help IT students get experience in the industry. Last year I applied and ended up working over summer for ProjectX. I applied again this year, largely because it means I don’t have to go applying to companies myself, and because law firms won’t take me yet (there’s no future in the law anyway, apparently, so it’s probably for the best). For my part of the process, I had to prepare my CV (untouched since the last Summer of Code), sit a test which ranked me against other applicants, have interviews with a number of companies (in my case eight), and select which companies I could bear to work three months for. The companies then listed the students in order of preference, and some algorithm matched the applicants with the companies. I was matched with Mindscape, which was incidentally the only company in the interviews that required applicants to write code.

Mindscape and Me

I began this week working here at Mindscape. I’ve been working for the past few days learning about LightSpeed, and getting up to scratch with the .NET framework. Over my time here, I’ll be working on a number of projects, some of which, excitingly, may even be available for all the world to use (or at least the part of the world that use LightSpeed).

Mat

LightSpeed 1.1 Released

tag icon Tagged as LightSpeed, News, Products

Today we’re pleased to announce the release of LightSpeed 1.1. This is a major release incorporating many new features and improvements all based on real-world customer feedback. Let’s take a look at some of the highlights…

h3. Soft Delete.

We now support “soft delete”. With soft delete entities are never physically deleted, but instead marked as deleted using a timestamp field.

To enable soft delete simply add a _DateTime?_ field called “deletedOn” (or _deletedOn) like so:

// class Customer
 
private readonly DateTime? _deletedOn = null;
 
public DateTime? DeletedOn
{
  get { return _deletedOn; }
}

Now when we query _Customer_ like so:

long count = Repository.Count<Customer>();

The sql produced looks like this:

SELECT
  COUNT(*)
FROM
  Customers
WHERE
  Customers.DeletedOn IS NULL

Of course, the extra SQL criteria are also applied appropriately when using eager loading.

If you need to get hold of entities marked as deleted then you can tell LightSpeed to omit the checks. To do this simply set the _IncludeDeleted_ property on the _Query_ object.

h3. Polymorphic Querying.

In 1.1 we’re making it easier to query specific types in an inheritance hierarchy. Previously, if we wanted only _GoldCustomers_ from our _Customer_ hierachy, we would have to manually add the discriminator criteria to our query. Now we can just ask LightSpeed to return just the _GoldCustomers_ (or any descendents of).

IList<GoldCustomer> = Repository.Find<GoldCustomer>();

And the SQL produced will look something like:

SELECT
  Id,
  CustomerTypeId,
  Name,
  Discount
FROM
  Customers
WHERE
  Customers.CustomerTypeId = 2  -- 2 for Gold Customers

h3. Validation

Validation received much love in 1.1:

We’ve added a _Validating_ event that gives you a little more control over the validation of an entity. Specifically, this event is fired just before an entity is validated and gives you the option of skipping validation for the entity.

Based on customer feedback, we also changed the validation algorithm so that it now walks the graph of associated entities. Let’s say our _Customer_ class has an associated collections of _Purchases_ and that a _Purchase_ must have a positive _Amount_. _Customer_ is our aggregate root here so our code may look something like this:

Customer customer = Repository.Find<Customer>(1); // find customer with id == 1
customer.Purchases.Add(new Purchase());  // oops, didn't set the purchase amount
 
Repository.CompleteUnitOfWork();

As expected, _CompleteUnitOfWork_ throws a _ValidationException_ because our new _Purchase_ has an invalid _Amount_. The error message looks something like this:

_Mindscape.LightSpeed.Validation.ValidationException : The object [Customer[Id=1, EntityState=Modified]] could not be saved because it is invalid.

The errors are:

  Purchases item 0 is invalid

    Amount is required_

We also added scoping to the _ValidateUnique_ attribute. This allows you to more finely limit the range of a uniqueness validation check. Usually, a _ValidateUnique_ rule results in LightSpeed issuing a query similiar to:

SELECT
  COUNT(*)
FROM
  Customers
WHERE
  (Customers.Name = 'Ivan' AND Customers.Id <> 42)

If however, we were only concerned with _Name_ being unique within the scope of _CustomerTypeId_, we would apply the validation like so:

[ValidateUnique("CustomerTypeId")]
private string _name;

With the scope applied LightSpeed adds the scope check to the resulting validation query:

SELECT
  COUNT(*)
FROM
  Customers
WHERE
  (Customers.Name = 'Ivan' AND Customers.Id <> 42 
  AND CustomerTypeId = 2) -- Ivan is a Gold Customer

h3. Default Order Attribute.

We’ve introduced an attribute to allow you to control the default order applied when querying. The new attribute can be applied at the class or association level like so:

[OrderBy("Subject")]
public class Customer : Entity<int>
{
  [OrderBy("Amount ASC")]
  public readonly EntityCollection<Purchase> _purchases
    = new EntityCollection<Purchase>();
 
  //...
}

At the class level, LightSpeed will apply the default ordering to any queries that have no explicit order specified. At the association level, as with _Purchases_ in the example, LightSpeed will apply the default ordering when loading the associated collection (eager or lazy).

h3. Performance Improvements.

We refactored some core components of our mapping engine. You should notice some nice performance improvements across all areas of the framework.

h3. Inheritance Mapping.

We fixed quite a few edge case bugs around inheritance mapping. Additionally, we made some improvements to how discriminator attributes are handled:

Discriminator fields are now automatically initialized:

Customer goldCustomer = new GoldCustomer();
// goldCustomer.CustomerTypeId == 2

Discriminator fields can now be enums:

[Discriminator(Attribute = "CustomerTypeId", Value=CustomerTypes.Gold)]
public sealed class GoldCustomer: Customer
{
}

h3. Read-only Fields.

Any field declared _readonly_ won’t be included in any save operations. This is useful for derived columns or if you are backing on to an updateable view instead of a table.

h3. Identifiers Only Query Option.

The LightSpeed _Query_ object now contains an _IdentifiersOnly_ property. Set this to _true_ and LightSpeed will return a collection of object identifiers rather than complete entities.

h3. Nested Unit of Work.

Occasionally it is useful to be able to have multiple units of work alive within the same scope. LightSpeed 1.1 now supports this through the concept of a nested unit of work. To create a nested unit of work simply call the _Repository.BeginUnitOfWork_ method. This method effectively pushes a new unit of work on to an internal unit of work stack making it the new current unit of work. Calling _Repository.CompleteUnitOfWork_ will dispose the nested unit of work and pop it from the stack causing the previous unit of work (if any) to become current.

h3. Samples & Documentation

We’ve spent a good deal of time in 1.1 trying to make the documentation and samples even better. We’ve included a new VB sample and also included a small sample illustrating how LightSpeed passes the “Mats Challenge”:http://www.matshelander.com/wordpress/?p=55.

h3. Special Offer

To celebrate this release we’ve decided to run a limited time special offer. Get LightSpeed Standard for $99 and LightSpeed Professional for just $299.

So what are you waiting for? Go grab the free “LightSpeed Express”:http://www.mindscape.co.nz/Downloads/LightSpeedExpress.msi version and kick the tires. As always, we’d love to hear any feedback.

Cheers,

Andrew.

kick it on DotNetKicks.com

LightSpeed featured on ARCast.TV

tag icon Tagged as LightSpeed

At TechEd New Zealand earlier this year Jeremy and myself had the fortunate opportunity to catch up with Ron Jacobs, the host of ARCast.TV. After finding a quiet room we got talking about the 1.0 release of LightSpeed and why we believe it’s a fantastic tool for creating rich domain models.

Click here to watch LightSpeed on ARCast.TV

– JD

kick it on DotNetKicks.com

Data Products Visual Controls Community Store
LightSpeed ORM
NHibernate Designer
SimpleDB Tools
SharePoint Tools
WPF Elements
WPF Diagrams
Silverlight Elements
Forums
Blog
Register
Login
Subscribe to newsletter
Buy Now
My Account
Volume Discounts
Purchase Orders
Contact Us