Home » Blog

rounded header

Archive for January, 2009

LightSpeed, WCF and Serialization

tag icon Tagged as LightSpeed, Products

It seems that developing with LightSpeed and having distributed scenarios in mind is becoming very popular based on all the queries we have received recently in the forums around how LightSpeed plays with WCF :)

In the earlier releases of LightSpeed 2, we supported distributed scenarios in 2 ways. Firstly LightSpeed entities could be serialized by using either the XmlSerializer (e.g. with ASP.NET ASMX web services) or using the DataContractFormatter with WCF. Generally we would encourage you to use WCF due to the serializer being a bit smarter, particularly at handling graphs of objects which you typically encounter in your models.

In LightSpeed 2.2 we are adding some interim support to the generator to allow some standard Data Transfer Objects (DTO’s) and convertor functions for mapping between the entities and DTO’s to help save you some time.

An example would be, given an Employee entity such as the one we use in our samples, we would generate you a DTO called EmployeeDTO already decorated for use with WCF;

  [DataContract]
  public class EmployeeDTO
  {
    [DataMember]
    public string LastName { get; set; }
    [DataMember]
    public string FirstName { get; set; }
 
    // .. and so on for each entity property
  }

and then a convertor function such as;

public static Converter<employee , EmployeeDTO> ConvertEmployee =
      (employee) =>
      {
        return new EmployeeDTO() 
        {
          FirstName = employee.FirstName,
          LastName = employee.LastName
 
	  // ... etc
 
        };
      };

So you can perform operations such as;

EmployeeDTO[] allEmployees = 
  unitOfWork.Find<employee>().ToArray(DTOConvertor.ConvertEmployee);

or

EmployeeDTO singleEmployee =
  DTOConvertor.ConvertEmployee(unitOfWork.FindOne<employee>(1));

Going the other way you will likely want to map the fields on the inbound DTO back on to an existing or new LightSpeed entity, so we generate a similar style extension method such as;

Employee employee = singleEmployee.MapTo(unitOfWork.FindOne<Employee>(1));

In LightSpeed 3.0 we will be catering for distributed scenarios in a much more structured and supported way and we will provide some more concrete example of these closer to release :) If you are working with LightSpeed in a distributed scenario currently or are thinking of doing so, drop us a line in the forums – we would love to hear from you and work with you during the 3.0 timeframe to get the bits you need in there!

Teaser: WPF Flow Diagramming

In the very near future we will be releasing a beta version of our WPF Flow Diagramming control. A fairly specialised control but something that hopefully WPF developers out there will find useful.

Here’s a screenshot of an early version that will be going out for public beta testing soon:

Mindscape WPF Flow Diagraming Framework Beta Screenshot

The beta is not yet open and we will announce when we do make beta builds available. If you would like to be put on the list then please email me your contact details (jd@mindscape.co.nz).

As always, we appreciate any feedback you have – drop a comment below!

Coming soon: ASP.NET Dynamic Data for LightSpeed

tag icon Tagged as LightSpeed

One of the cool features in .NET 3.5 SP1 is the Dynamic Data feature for ASP.NET, which dynamically builds Web pages based on your model instead of you having to hand craft them or regenerate code all the time. In LightSpeed 2.2 we’ll be including a library that enables Dynamic Data to work with LightSpeed entities. This is a quick way to create simple sites while still taking advantage of LightSpeed features such as validation, or to create a “raw” view for administrators who need to be able to get right down to the object model.

We’ll post more about this as the feature matures, but here are a couple of screenshots to whet your appetite.

Dynamic Data list screen

Dynamic Data edit screen

Stay tuned for more information over the next couple of weeks!

Object-relational mapping over Amazon SimpleDB using LightSpeed

One of the features we’re adding in LightSpeed 2.2 is support for Amazon SimpleDB, and an early version of this is already in the nightly builds. Here’s a preview of how to use it and what you can do with it.

First, some background. LightSpeed pretends that SimpleDB is a relational database, treating SimpleDB domains as tables and pretending that all items in the domain have the same set of attributes. LightSpeed also assumes, again on the relational model, that an item attribute has at most one value. (We’ll be looking at supporting multiple values for an attribute, but probably not in the 2.2 timeframe.) So all the familiar LightSpeed conventions apply: entity types map to domains, associations are expressed by references to IDs (item names) in other tables, and so on.

Consequently, most of the additional LightSpeed magic also just works: for example, you can do single table inheritance using a discriminator attribute or many-to-many associations using a through-table and a ThroughAssociation, you can make full use of the validation functionality, and you can query SimpleDB using LINQ. (There are some things we can’t do because of limitations in the SimpleDB platform: for example, there’s no eager loading and no querying across tables.)

Let’s get started. If you’re using the designer, you can use SimpleDB Management Tools to drag and drop domains from Server Explorer. The free version will do, or if you’re an Enterprise customer, the retail edition is included with your Enterprise licence. Note that SimpleDB, unlike a relational database, doesn’t have “columns” independent of values to go in them, so if you don’t have existing data, you’ll get an empty entity and will need to add properties by hand. But if you do have existing data, the designer will create the entity properties for you.

LightSpeed model from SimpleDB

(In this example I’ve changed the entity Identity Type from the default String to Guid. This automates assigning item names to new items, at the expense of not being able to work with arbitrary item names.)

You can now work with this just as with any other LightSpeed model:

LightSpeedContext<DemoUnitOfWork> context = new LightSpeedContext<DemoUnitOfWork>
{
  DataProvider = DataProvider.AmazonSimpleDB,
  ConnectionString = "Access Key=...;Secret Access Key=...",
  IdentityMethod = IdentityMethod.Guid
};
 
using (DemoUnitOfWork unitOfWork = context.CreateUnitOfWork())
{
  IList<Game> games = unitOfWork.Find<Game>(Entity.Attribute("Price") < 30.00m);
 
  foreach (Game game in games)
  {
    Console.WriteLine("{0} by {1}: {2:C}", game.Name, game.Designer.Name, game.Price);
  }
 
  Game carcassonne = new Game
  {
    Name = "Carcassonne",
    Price = 20.95m,
    GameType = "1",
    OnlinePlayAvailable = true,
    Designer = new Person { Name = "Klaus-Jurgen Wrede" }
  };
 
  unitOfWork.Add(carcassonne);
  unitOfWork.SaveChanges();
}

As you can see, you can use the normal LightSpeed query API, you can traverse and create associations, and so on. You can also use LINQ to perform the query:

var games = from g in unitOfWork.Games
            where g.Price < 30.00m
            select g;

As a final demonstration, here’s a slightly more advanced model, using single table inheritance to store multiple entity types in a single domain:

LightSpeed model for single table inheritance over SimpleDB

The Game domain now contains both BoardGames and VideoGames, but LightSpeed inheritance takes care of distinguishing the two and materialising them using the correct types:

foreach (BoardGame game in unitOfWork.BoardGames.Where(g => g.Price < 30m))
{
  // VideoGames don't have a Designer, but the query returns only BoardGames
  Console.WriteLine("{0} by {1}: {2:C}", game.Name, game.Designer.Name, game.Price);
}

This demonstrates how LightSpeed adds significant capabilities over the raw SimpleDB API: not just an object-oriented wrapper around the data, but a way to abstract out common patterns and conventions from the relational world and apply them in the SimpleDB environment.

Want to try it out yourself? Get the latest LightSpeed nightly build — the free version is here — and optionally SimpleDB Management Tools and you’re ready to go!

kick it on DotNetKicks.com

Creating LightSpeed Context?

tag icon Tagged as LightSpeed

In the getting started with LightSpeed screencast I demonstrated the creation of a LightSpeed Context. A LightSpeed context is effectively a holder of information about one of your connections/databases. The norm is to use only one context because you’ve built an application that only talks to one database. LightSpeed does however support the ability to chat with several databases at once and therefore you can create several contexts.

In the video I had a property that when accessed created a LightSpeedContext() object and stored it in local scope for future use. The code looking something like this:

public static LightSpeedContext<ModelUnitOfWork> Context
{
  get
  {
    if (_context == null)
    {
      _context = new LightSpeedContext<ModelUnitOfWork>();
 
      // For illustrative purposes only -- better way shown below!
      _context.ConnectionString = LightSpeedContext.Default.ConnectionString;
      _context.PluralizeTableNames = LightSpeedContext.Default.PluralizeTableNames;
      _context.IdentityMethod = IdentityMethod.KeyTable;
    }
 
    return _context;
  }
}

This code showed that you could configure the context in code and read values off the default context that was configured in the .config file.

Hang on – we already have a context you say?

One thing that you may wonder about is why we couldn’t just use LightSpeedContext.Default? It is a ready-to-run LightSpeedContext after all.

The reason is that I wanted to use the LightSpeed LINQ API. The LightSpeedContext.Default is not strongly typed with the generic argument of and therefore would be missing the IQueryable collections for each of the entity types. The best way to demonstrate the difference to developers is to look at the intellisense output of the two types:

Strongly typed unit of work verse non typed

Notice that the only real difference is that there are collection properties of CartItems, Carts, Customers etc in typed unit of work.

Why have both? The strongly typed UoW is a convenience helper for the standard UoW. It is not providing anything you cannot do with the standard UoW, it’s just wrapping up some model-dependent boilerplate such as LINQ queries and stored procedure calls. The benefit of this is that at the expense of creating a strongly typed unit of work you get a lot of nice benefits for the rest of your development.

Now when we want to write LINQ queries we can write:

unitOfWork.Customers.Where(c => c.FirstName == "Chuck")

We couldn’t do that without the Customers collection.

Could we improve your example anyway?

Certainly! As I mentioned in the screencast, the implementation was just a quick setup to demonstrate how to get started. The way that you work with your context and unit of work is entirely dependent on your architecture.

In terms of reducing just the number of lines written in the simple example I used, we can throw away the awkward assignment of configuration values:

_context.ConnectionString = LightSpeedContext.Default.ConnectionString;
_context.PluralizeTableNames = LightSpeedContext.Default.PluralizeTableNames;
_context.IdentityMethod = IdentityMethod.KeyTable;

This was a tedious and redundant step but was important to show that you could configure the context in code. It is also handy when you just want to update a single value when debugging. We can however throw that all away with this code:

public static LightSpeedContext<ModelUnitOfWork> Context
{
  get
  {
    if (_context == null)
    {
      _context = new LightSpeedContext<ModelUnitOfWork>("default");
    }
 
    return _context;
  }
}

This would automatically apply the configuration from the .config file, picking up the configuration of the context named “default”, saving us time if we ever added a new configuration value in the .config file (for example, logging).

I hope that helps with understanding how the context can be manipulated, setup and used in different scenarios. As always, leave a comment if you have a question or feedback!

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