Home » Blog

rounded header

Large models in LightSpeed 3.1 – Part 2

tag icon Tagged as LightSpeed

In a previous post, I talked about some of the issues that arise when you want to work on a large model in a visual designer, and some enhancements in LightSpeed 3.1′s filtered views feature to get around those issues. However, a model with filtered views is still a monolithic model. Sometimes you want to be able to split your model across multiple files. In a large system, for example, you don’t want the model file to become a bottleneck: it’s useful for multiple developers to be able to work on different parts of the model at the same time. It’s also good discipline to try to partition the model up into discrete subsystems so as to minimise coupling between those subsystems: this allows the subsystem models to evolve independently as requirements change and the domain is modelled in more detail or needs to reflect changes in the real world.

For example, in an order fulfilment model you might identify three major areas: orders, logistics and customers. Each of these areas has a potentially complex internal model, but has relatively few links to the other areas. They’re not completely isolated, of course: a customer has orders, an order has shipments. But they can be developed independently: you can refine the way warehousing is modelled without having to muck around with the way orders or customers are modelled; and conversely things in the orders or customers sub-domains may care about shipments, but probably don’t care about anything deeper in the logistics domain.

In LightSpeed 3.1, you can represent a semi-partitioned domain like this using linked model files.

The pattern of internal cohesion with relatively few external links is characteristic of a good sub-domain, and it’s the key to using linked models. Linked models need some external references — otherwise there’s be no point linking them! — but you want to minimise these, so that each linked model is as standalone as possible. Otherwise you end up having to jump between models to make changes, which cancels out the simplicity benefits of splitting the big model in the first place. Thus, in this example, we’d create three linked model files: Orders.lsmodel, Logistics.lsmodel and Customers.lsmodel.

With linked model files, we can represent each sub-domain in its own file, with entities that are defined in other files but needed for associations represented as entity links. Here’s how it looks:

Notice how PurchaseOrder in the Orders sub-model is able to link to Customer in the Customers sub-model and Shipment in the Logistics sub-model via entity links to the Customer and Shipment entities:

How do I link model files?

A LightSpeed designer model has a Name property, which you can see and edit by clicking on the model background and going to the Properties window. Two models with the same Name are linked. It’s that easy.

Really? It’s that easy?

Well, it’s almost that easy. There are a couple of extra rules. First, the Target Namespace settings of the models must also be the same. Most people leave the Target Namespace as the project namespace, so you don’t normally need to do anything here. Second, all but one of the linked files must have Is Linked Child set to True. It doesn’t really matter which one is the “parent” — it’s just that there’s some code that we have to generate once and once only, so we have to pick a file to host that once-only code.

But apart from those two wrinkles, it’s that easy.

Couldn’t you make it any easier?

Sure. If you’ve got a model which is starting to get a bit on the bulky side, you can right-click a one-to-many association that divides the model in two and choose Refactor > Split Model at Association. (If there’s no one single association which splits the model in two, you can select multiple one-to-many associations which between them split the model in two.) Enter the name of the new file, choose which half of the model you want to move into the new file, and Bob’s your uncle. The new file will automatically be given the same model name and target namespace as the “parent” file, and will be set as a linked child.

Also, if you use the Paste as Link command to create an entity link, it will check that the two files are linked, and offer to link them if they’re not.

So I have my linked files. How do I make a model that spans them?

As discussed above, linked models work best when there are relatively few associations that span files. If you have too many associations that span files, then you’ve not got good isolation between your sub-domains, and you’re likely to have to alter multiple files to make any change. But of course you need to be able to create some associations that span files. Here’s how.

First, identify the two entities you want to associate. Let’s say you want to model that an Order has a collection of Shipments. Order is defined in Orders.lsmodel and Shipment in Logistics.lsmodel.

Second, copy each of those entities in turn, and use the new Paste as Link command to paste a link to that entity into the other file. For example, select the Shipment entity in Logistics.lsmodel, press Ctrl+C to copy it to the Clipboard, switch to Orders.lsmodel, right-click the background and choose Paste as Link. You’ll see an entity link appear in Orders.lsmodel — you can tell it apart from a normal entity because it has a link icon and says “Link to” in its descriptive text.

Now do the same operation in reverse, copying the Order entity from Orders.lsmodel and pasting it as a link into Logistics.lsmodel.

Third, create the association in both files. In each case, you create the association normally, by selecting OneToManyAssociation from the toolbox and dragging an arrow from Order to Shipment. But you need to do it twice: once in Orders.lsmodel and once in Shipment.lsmodel.

Save the files and you’ll now find that your Order class includes a Shipments property and your Shipment class includes an Order property! Of course you can rename the ends of the association and set properties as usual — just remember to do it in both places.

Man, that’s like fourteen clicks.

I warned you! Cross-file associations aren’t as convenient as intra-file associations. If you’re having to create a lot of them, maybe you should be splitting your model in a different place. Or maybe linked models aren’t a good fit for your problem domain.

Yeah, but fourteen clicks. I’m a busy guy. Minesweeper doesn’t play itself, you know.

A lot of models are evolutionary: that is, rather than creating three .lsmodel files on day one, you’ll start out with a single .lsmodel file, and break it up about the eighteenth time someone else asks you when you’ll be finished with it. When this happens, you can use the Refactor > Split Model at Association command to partition the model. This will create the necessary links and “duplicate” associations. Three clicks and a few keystrokes.

We’ll also be working to improve this experience in future nightly builds.

Anything else I need to watch out for when using cross-file associations?

It’s important to realise that entity links aren’t really links — they’re more like references, and they can get out of date. If you change, say, the identity type of the entity, you need to update the links to that entity to reflect that change. Similarly if you have a cross-file association and you change its properties, you need to change them in both places.

Fortunately, LightSpeed does give you a bit of help with this. You can right-click a linked model and choose the Check Links command to verify that links and associations are up-to-date. For some inconsistencies, LightSpeed can fix the problem automatically: we can’t yet do this for all inconsistencies, but again it’s something we plan to improve in the nightly builds.

Where can I get it?

Linked models are supported in all editions of LightSpeed 3.1, in both Visual Studio 2008 and Visual Studio 2010. If you’re a customer, LightSpeed 3.1 is in the store now. If you’re not… well, normally at this stage I’d exhort you to download the free Express edition and give it a try, but the free Express edition is limited to eight entity types, which hardly counts as large model territory. But what the heck. We think this is a pretty handy feature for dealing with large models, and we’d love to hear your feedback on how we can improve it. So go ahead: download it anyway.

5 Responses to “Large models in LightSpeed 3.1 – Part 2”

  1. That feature is outstandig! Well done :-)

    I would like to get an option to navigate from an “Link to Entity” to the model with the “real” defintion of that specific Entity.

  2. Doh! I can’t believe I forgot to mention that. It’s already in there: right-click the entity link, and choose Go To Linked Entity. (Be warned this will currently only take you to the model containing the real entity: it won’t select the entity itself.) Thanks for reminding me!

  3. :-)

  4. I ran into a gotcha doing this… any additional models that you link must have the IsLinkedChild property set.

    For the full story, see Ivan’s full response to my request for help here: http://www.mindscape.co.nz/forums/Post.aspx?ThreadID=3600&PostID=12279

    or here is the relevant snippet:

    “Open each file, click on the background, and make sure that IsLinkedChild is set to False on one model and True on all the others. A set of linked models must contain exactly one primary model (non-child) model.”

  5. Thanks for posting the note there Alex – much appreciated :-)

Leave a Reply

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