Wednesday, December 21, 2011

Custom Controls vs. Extensions

Did you know that, although I have previously voted for extensions, my experience with LightSwitch helped me realize that in some cases custom controls can be more effective than extensions or even handle issues extensions are not meant to handle.

When special manipulation and user interaction has to be handled (like drag’ n’ drop handling especially between differently typed collections) although extensions can be employed, IMHO, the plumbing needed to achieve the desired goal is to be taken under serious consideration. In general the question to be answered, as to whether one should implement an Extension Control or a Custom Control, is if the effort needed to extract the general behaviors and characteristics required by the entities to be handled and thus generalize the control, is worth it. And by “worth it” I mean what are the chances one will be able to reuse it.

There are cases that very special data manipulation requirements need to be met (once and maybe never again). In these cases a “Project” Custom Control (proprietary terminology) is the best solution. By “Project” I mean a custom control that is aware of the domain. Created in the Client project maybe or any other project with a reference to the Client project. The Client project apart from being aware of the domain has also direct reference to the concrete client LightswitchApplication with all the plumbing required to have access to the concrete Dataworkspace.

One thing is for sure, as soon as you have a custom control operating without having concrete reference to your domain and application, you have a perfect candidate for a Control Extension and you should implement it as soon as possible.

Sunday, November 20, 2011

Auditing and Concurrency don’t mix (easily)…

In MSDN forums I came across a post addressing an issue I have also faced. Auditing fields can cause concurrency issues in LightSwitch (not exclusively).
In general basic auditing includes keeping track of when an entity was created/modified and by whom. I say basic auditing because auditing is in general much more than this.
Anyhow, this basic auditing mechanism is very widely implemented (it’s a way for developers to be able to easily find a user to blame for their own bugs :-p), so let’s see what this can cause and why in LightSwitch.
In the aforementioned post but also in this one, I have clearly stated that IMHO the best way to handle concurrency issues is using RIA Services. If you don’t, read what follows.
Normally in any application, updating the fields that implement Audit tracking would be a task completed in the business layer (or even Data layer in some cases and this could go as deep as a database trigger). So in LightSwitch the first place one would look into to put this logic would be EntityName_Inserting and EntityName_Updating  partial methods that run on the server. Which is right, but causes concurrency issues, since after saving the client instance of the entity is not updated by the changes made at the server and as soon as you try to save again this will cause concurrency error.
So, what can you do, apart from refreshing after every save which is not very appealing? Update at the client. Not appealing either but at least it can be done elegantly:
Let’s say all entities to implement auditing have 4 fields:
  • DateCreated
  • CreatedBy
  • DateModified
  • ModifiedBy
Add to the Common project a new interface called IAuditable like below:

namespace LightSwitchApplication{
    public interface IAuditable{
        DateTime DateCreated { get; set; }
        string CreatedBy { get; set; }
        DateTime DateModified { get; set; }
        string ModifiedBy { get; set; }
    }
}



Then, also in the common project, add a new class called EntityExtensions:
namespace LightSwitchApplication{
    public static class EntityExtensions{
        public static void Created<TEntityType>(this TEntityType entity, IUser user)
           where TEntityType: IAuditable{
           entity.DateCreated = entity.DateModified = DateTime.Now;
           entity.CreatedBy = enity.ModifiedBy = user.Name;
        }

        public static void Modified<TEntityType>(this TEntityType entity, IUser user)
           where TEntityType: IAuditable{
           entity.DateModified = DateTime.Now;
           entity.ModifiedBy = user.Name;
        }
    }
}



Now let’s suppose your entity’s name is Customer (imagination was never my strong point), the screen’s name is CustomerList and the query is called Customers.

First Viewing the Customer entity in designer click write code and make sure that:
partial class Customer : IAuditable{
}

Then at your screen’s saving method write this:
partial void CustomerList_Saving{
    foreach(Customer customer in this.DataworkSpace.ApplicationData.Details.GetChanges().AddedEntities.OfType<Customer>())
        customer.Created(this.Application.User);
    foreach(Customer customer in this.DataworkSpace.ApplicationData.Details.GetChanges().ModifiedEntities.OfType<Customer>())
        customer.Modified(this.Application.User);
}


This should do it. This way you can also easily move your logic to the server as the interface and extension class are defined in the Common project and they are also available to the server.
 



Tuesday, November 8, 2011

CLASS Extensions. Making of (the end)

If you have installed CLASS Extensions you know that there are two different controls that are used to handle Color business type. The ColorPicker and the ColorViewer. If you have read the previous post of the series you know that behind the scenes, each one of these controls is a wrapper for 2 other controls. The ColorPicker is for editing whereas ColorViewer is used for viewing only. The reason of exposing 2 different controls was that I didn’t manage to correctly retrieve the information about the content being read-only and changing dynamically the behavior of the controls.
If you browse the code you will see in <Control>_Load and other places (be kind, I was desperate) the attempt to bind to IsReadOnly property of the DataContext.
What I wanted to achieve was to support the “Use read-only controls” functionality. As I wrote in the previous post I was very close. I found out after publishing that the IsReadOnly property was set ONLY when the field or the whole dataset was read-only, like a calculated field or a view-dataset (containing data from more than one source or directly mapped to a DB view). What I was looking for was a property I found out digging exhaustively down the Quick-Watch window, called …(drum-roll) IsBrowseOnly. After discovering it and search back against the documentation, still didn’t manage to locate any reference to this property.
Anyway all well that ends well. Took me some time but as I mentioned in a previous post of the series, I was prepared, given that documentation is far from being complete and definitely there is nothing like a complete Reference Guide, or maybe I am not good at reading it :-).
So, IsBrowseOnly binding, along with designer initial settings issues solved, and 3 new business types (Rating, AudioUri and VideoUri) will be included to the next version of CLASS extensions. Code will, most probably, not be published this time. So keep an eye open and stay tuned…Winking smile

Saturday, October 29, 2011

CLASS Extensions. Making of (Part II)

Crashing your LightSwitch project with your extensions is a piece of cake. The first simplest thing I did was change the business type to handle integer values instead of string ones. But I changed “:String” to “:Int”. That was enough to do it. It should be “:Int32”.
So, after managing to create and use (declare as a type for an integer field in an entity) my business type, keeping my LightSwitch project in one piece, I had to work on my control. As I have already mentioned I had my custom control ready and tested, so, it should be easy.
I had used my custom control only in detail parts and although the expander used was “deforming” the layout when expanded (I have to fix this anyhow in the future) everything were going back to normal after collapsing the expander. This was not so for collections. Using my control in a grid the result after collapsing the color picker control was a grid row having a height of the expanded control. The reason is that the grid rows are auto-sized and have no specific height so…
I was only after having implemented a wrapper control to provide 2 different controls, one for collections and one for details, based on the reply by Justin Anderson to a thread initially intended to help me handle read-only controls, that I got an answer from Silverlight forum where I knew it was the right place to post my question. Either way, implementing what the reply suggested (although it works fine) required a lot of handling of transitions between expanded and collapsed. Also the “deform” in a grid when the control is expanded(even temporary) is, in my opinion, more annoying than in details.

if ((this.DataContext as IContentItem).ContainerState.HasFlag(ContainerState.Cell)) {
  ColorControl control = new ColorControl();
  control.DataContext = this.DataContext;
  control.SetBinding(ColorControl.IsReadOnlyProperty, new Binding("IsReadOnly"));
  MainGrid.Children.Add(control);
}
else {
  ColorPickerDrop control = new ColorPickerDrop();
  control.DataContext = this.DataContext;
  control.SetBinding(ColorPickerDrop.IsReadOnlyProperty, new Binding("IsReadOnly"));
  MainGrid.Children.Add(control);
}


In the code above you can see selecting the control to “use” based on the ContainerState property of the IContentItem that is passed as DataContext. You can also see the attempt to make the control read-only. My attempt was to make the controls automatically read-only when “Use read-only controls” is checked from the designer. I was that close…
Also for some reason my control when implemented in extension tended to take too much space by default. I had to change alignment to left/top by hand. It was only after releasing the first (and only one available until now) version that I managed to handle this along with other issues regarding designer behavior.
Hopefully before the end of 2011 I will be able to publish the next version, which contains also one more business type (rating) and respective control.
In the next post I will discuss the read-only issue that I didn’t manage to deal with in the published version…

Sunday, October 23, 2011

CLASS Extensions. Making of (Part I)

I haven’t been able to post during the last week. It’s been a very hectic week and I didn’t have time or when I did have the time I didn’t have the courage…
Anyhow, I am going to share with you issues I had to face creating my first LightSwitch Extensions project.
First thing was to create the Color business type. I already had custom Silverlight control and value converters I had already published in a sample in MSDN’s LightSwitch Developer Center. So half of the work was done, right? Well, not quite…
I must say here that many of the problems were a result of the fact that editing the lsml file is very error prone as there is nothing to help you while editing the file by hand. I mean it’s not like editing the XAML of a Silverlight control, with code completion, syntax checking and all the goodies. It’s raw XML editing. And the thing with errors in lsml is that the result is terrifying…a tag improperly closed crashes the universe. The LightSwitch test project becomes unloadable (screens and data sources disappear). Of course it’s only temporary since as soon as you fix the syntax or spelling error everything (no matter if the extension works as expected or not) comes back to normal. There are a few things I learned during the numerous (to say the least) trial and error editing-running-debugging cycles and I want to share. They are not advices they just that; sharing:
  • When the above mentioned mess happens (the test project fails to load) the best thing to do is try to build. Most (not all, depending on the kind of error) of the times examining the error list bottom-up, you can deduce useful information about the origin of the error and where is the lsml is the error.
  • Make small changes between testing cycles as this makes it, obviously, easier to locate any potential syntactical or spelling error. This is one of the most important rules of thumb I ended up with.
  • Copy-paste-modify of correct xml blocks is the safest way to minimize syntactical and spelling errors. In general, I dislike copying blocks of code because I fill like I am using something I don’t understand, even if it’s not really so. But, in this case I ended up copying whole blocks of XML from the How to articles and edit afterwards and it felt right…
  • And one last practical thing. The procedure that worked better for me, regarding debugging the extensions was not the one suggested and preconfigured when creating an extension project. I had various debugging issues I didn’t manage to identify and solve. Most probably it’s something I was doing wrong since the procedure described in the above link is used for all extensions of VS for quite some years. Anyhow, for what it might worth what I did was:
    1. I created a LightSwitch project in the same solution as the extension that used the extension.
    2. When I wanted to test a change, I was going to Extensions Manager and uninstall the extension. I closed the Extensions Manager (don’t press Restart Now, not now)
    3. Right click the vsix project select build.
    4. After build right click and choose Open Folder in Windows Explorer. Install the package from the bin folder.
    5. Go back to Extensions Manager and choose Restart Now, now.
I know these are more procedure details, rather than technical or implementation ones, but I wanted to share with anyone that might be interested. In the next post, which I hope I will write in the next couple of days, I will share more technical details like read-only, collection / details controls, handling nullable types.
I guess I have to change the subtitle of the blog from “daily updated” to “frequently updated”Winking smile

Sunday, October 16, 2011

CLASS Extensions. Making of (the origins)

Did you know that the main reason I created CLASS Extensions was to make my life easier?
I had initially discarded LightSwitch from my deck of choices. At first glance (early Beta 1) I had misjudged it as poor relative of application builders that I hate altogether.
It was after watching Beth Massi’ s presentation in Tech-Ed USA 2011 regarding extensibility that made me take a second good look at it. And then…then it was love at second sight.
Although extensibility was what made me love LS, it took me quite some time to decide to write my own extension. I had custom controls I was using (the Color business type and editors is an example) and referenced libraries for a long time as I was really intimidated by the idea of creating an extension of my own. And it was only after the official release of Visual Studio LightSwitch that I even thought of doing it, as the Cookbook  and blank template approach was, to say the least, discouraging, at least for me. I knew I wasn’t the intended audience.
When I started the development of the first application, I knew I had to write the extensions. Using the custom controls required so much duplication of logic mostly and code and was so restricting (as to how to name the members of the screens etc.) that made it unattainable to use them.
Just reading the How to articles on extensibility it was obvious the path to follow was there but many things were to be discovered and solve down that path, the hard way. I mean, it’s not the most complete and well structured documentation, but a wealth of information is provided.
“Be a man” I said to myself and created my first extensibility project. Took me a lot of effort to even have this, preliminary in terms of quality and completeness, version released. But, as I said in the previous post, as soon as I replaced the first custom control with the respective extension control I knew it was all worth it…Winking smile

Thursday, October 13, 2011

CLASS Extensions. Making of (Introduction)

Did you know that even for a simple extension there are numerous things the developer has to take into account?
I didn’t know it either until I decided to pack a few of the custom Silverlight controls and accompanying classes (like value converters) in CLASS Extensions. Many details, from very simple like setting the image of the control to be displayed in the LightSwitch designer, to more complex like automatically using one control for collections (like in a grid) and another for details and setting default settings. I must say here that if it weren’t for the community and all the members being more than willing to help, it would have been impossible to manage (what I have managed anyway, as this first attempt is far from complete).
It was the first time in my developer live I felt I really needed two screens. One for reading the proper LightSwitch extensibility How to article and one for the Visual Studio IDE to write code and XML. From these articles I managed to finally solve many of the issues reported in version 1.0 and will be included in the next version.
At the end of the day, I have to say that it was worth all the effort. Using extensions instead of custom controls and referenced libraries I had written and been using, is so much more productive that any time spent was paid back in just a few screens’ design time.
So, if you are hesitating to go through the process of learning how to write extensions, all I have to say is go for it! And this is a good tip…Winking smile
P.S. In upcoming posts I will talk  about the details of the implementation that i believe is worth sharing.

Wednesday, October 12, 2011

CLASS Extensions

Did you know a new free extension for LightSwitch has been published in VS Gallery?
Of course not. How on earth could you know that? I had to keep the “Did you know” pattern though…Smile.
The name is CLASS Extensions and you can download the extension either from Extension Manager of VS or from Visual Studio Gallery.
You can download the source code from here.
Feel free to ask questions either here or at the original Visual Studio Gallery contribution page.
Less boring than tips…Winking smile

Sunday, October 9, 2011

Extend your Business (types)

Did you know the best way to encapsulate and reuse parts of your business logic is writing Business Type Extensions?
Creating a Business Type extension you can encapsulate and reuse in all your projects part of you business logic, regarding validation, automatic calculation, but also UI logic writing default controls for your types if needed. For example almost all LOB applications need to be able to handle IBAN numbers.
One can easily implement a business type that will automatically check the validity of a string that is defined as IBAN business type and raise validation messages, or even (more advanced) present in a custom control the information contained in the IBAN number. Or a tax registry number, or a color stored as an integer or what ever will be represented as a typical type (string, integer, decimal etc) but it’s validation or UI display requires much more than just the typical. There are already many free and commercial extensions many of them containing (and) business types. You can find a list of extensions here.
We will talk about other types of extensions in next posts…Winking smile

Thursday, October 6, 2011

Concurrent or fast? I’d rather have both…

Did you know that concurrency provided automatically by LightSwitch might cause performance issues that you cannot easily trace?
LightSwitch uses Entity Framework’s concurrency mechanisms to ensure data consistency while 2 or more users modify the same entries. You can read about it in detail and with examples in this great (as always) post by Michael Washington.
The thing, though, is that using native data sources or SQL server imported data sources, LightSwitch applies concurrency checking to all fields and you can do nothing about it. So, what is wrong about that? The price you have to pay in performance terms is small in exchange to ensuring concurrency, one would say. Unfortunately this is not always the case. Apart from functionality issues that can easily come up (entities with last modification fields for example), there is one special but not so uncommon case that can kill your performance. Large binary fields. Images is the most common example. Checking images byte against byte with every record updated for modifications, is something that, in most cases at least, no one wants.
As in many other cases, RIA comes to the rescue. With RIA services, importing your domain objects in an EF entity model you can fully control which fields are checked for concurrency and which are not. Not only this, but also concurrency exceptions are passed-through to LightSwitch and the resulting behavior is exactly the same as if you were using native or SQL server imported data sources. This is great don’t you think…Winking smile

Wednesday, October 5, 2011

Sort This, you Light of a Switch

Did you know that LightSwitch by default cannot sort or search against lookup columns?
Sad but true. The native Data Grid of LightSwitch cannot sort or search against lookup columns. The good news is that, as always with LightSwitch, you have an option. Which is not at all bad, by the way. In non-editable grids, that is in search or list-detail screens, you can use views. Yes, database views that is. Another solution would be calculated fields, but, although simpler, performance is poor IMHO.
Views? How do I create views in LightSwitch? Well, you don’t. You cannot have views in native data sources (at least I am not aware of some way). But you can import them. Either with a SQL Server data source from an existing database, or with RIA Services data source.
Having a view containing the id of the entity (it doesn’t have to be visible) you can use it to either open the default detail screen on click, or, in the list detail scenario, remove the detail group, add the original entity’s collection query and filter it based on the selected item of the view query, or have a <EntityCollection>_SinlgeOrDefault query and bind the parameter to the view query's selected item id column. Then add a detail group for this query. You might have implementation issues you should deal with, but hey, this is a tips blog.
P.S.1 If you use or planning to use 3rd party controls your commercial data grid might solve this problem without all of the above. But If you don’t…
P.S.2 The whole truth (and nothing but the truth) is that you might have issues correctly importing views from SQL Server (regarding primary key for example, have you fixed it yet George?) so if I have to be honest, I must say RIA is the best way to go…Winking smile

Monday, October 3, 2011

The Lights Witch Project(s)

LWDid you know that when you create a new LightSwitch Application project beneath the Data Sources and Screens “Folders” live 5 projects in total?

Changing your view to File View Capture only “reveals” 3 of them: Client, Common, Server. If you choose to Show All Files ShowAllFiles 2 more appear: Client Generated, Server Generated. Now you have 5 projects in all. Ok, hurry back to Logical View, pretend you didn’t see this.Smile

Seriously now, the reason I include the beginners tag in posts like this one and this one, is because I am trying to make a point. LightSwitch is NOT the new Access. It’s much, much more than Access in terms on both potential but also complexity. LightSwitch Team has done a great job making the Logical View a user-friendly powerful application design environment. But, I believe it’s good to have a broad (at least) idea of what actually happens under the surface. This way when, for some reason (not very probable if you play with the designer only but always possible), you get a build error and clicking on that error a code file you have never seen before appears, you will not be terrified by the fact that someone has turned your beautiful screens and tables into ugly, messy code files.

Client Project: Is the project where the client application and accompanying code is found. In this project, in the UserCode folder, partial classes are automatically created and then populated by code every time you choose (for example) to Edit or Override Execute Code for a screen command. You also put your own classes there (but this is not beginner stuff…). It, very broadly, represents the presentation tier of your application.

Common Project: Is the project where business logic lies. Well, “Business Logic” has always been a bit vague to me as deciding what is business logic and what is not, is a bit foggy. I mean, deciding if a command can be executed under specific conditions or not is business or client? Client is the politically correct answer. To me this has always been a convention of thought. Anyhow Common contains all code that should be available both at the client and the server. One example is writing code for <Entity Name>_Created. This code is executed either at the client or at the server, hence Common.

Server Project: Is the project where the web application and the data-tier lies. An example would be <Entity Name>_PreprocessQuery methods when overridden, the code is included in Server\UserCode\<DataSource Name>Service.cs.

Client/Server Generated are complementary to the respective projects containing auto-generated code that you should never edit in any way (any change will be lost during the next build or modification made by the designer) and this is the reason why the are not visible in File View by default.

It’s better to know the enemy…Winking smile

Saturday, October 1, 2011

DisplayName like family name is inherited.

Did you know that setting the Display Name property of your table (entity) and all fields will make screen customization even easier?
All display names you define in your data sources are automatically used in all your screens. This practically leaves you with the collection name translations in the Screens as the display name of your table is used only in singular.
Also, not only new screens are initialized by display names defined at the table level, but if you don’t change a display name manually in a screen, any change made in the table is propagated to the screen.
This makes screen customization much easier and also localization.
For less beginners or more curious than average ones: What actually happens is that LightSwitch uses the DisplayName attribute (which decorates almost all objects and their properties in LightSwitch) which is inheritable, to…display names (what else). When you first create a screen (either you have changed the display name of the table column or not) you will notice Display Name fields in the properties pane are dimmed and oblique (italic). This is to denote DisplayName attribute has not been defined but inherited instead. Once you change the display name of a field on a form, it automatically acquires it’s own DisplayName attribute and therefore the DisplayName attribute of the table column stops being inherited any more.
Even elements not related to tables (layout groups for example) have by default their display name dimmed and oblique.
The full story is that for every single element LightSwitch first looks for an “explicit”, so to say, DisplayName attribute. If not found then it looks for an inherited one and if not found either (the case of a new group layout) then derives the Display Name from the Name property of the element (inserting space before every upper-case letter found after a lower case one).
I hope this was actually a tip and not a trip…Winking smile

Friday, September 30, 2011

Large Small Medium Large?

Did you know that everything you design in a LightSwitch application (tables, screens, queries etc) is stored in a file called ApplicationDefinition.lsml?
LSML extension stands for the title of the post…no, I’m kidding of course. It stands for LightSwitch Markup Language. This file can be found in the folder <Project Path>\<Project Name>\Data.
Working in Logical View this is file is not visible (no files are visible in this view either way). Turning to File View you can see links to this file in all three projects Client, Common and Server. Notice they are links. The original file is not included directly in any project.
The reason there is only one file and all projects have link to it, is that it’s common to all of them and any change made to it should be available simultaneously to all projects.
The reason it’s not included to any project, in my humble opinion, is mainly because it’s not meant to be edited in any way. It could be included in the Common project for example as it IS common.This file is the product of all designer work done in LightSwitch. Even when you change the Theme, or Access Type properties of the application from the Properties of the project this change is stored in this file.
This is the reason also, that only ONE (or none) “<Project Name> Designer” window is available at any given time in your workspace. Because there IS only one such window displaying a different part of the ApplicationDefinition.lsml file every time you double-click a table or a form or whatever opens a designer window.
One tip for the end. When you plan a major change in your model (data design), especially if you are NOT using a native datasource, keep a backup of ApplicationDefinition.lsml. If you are using version control, check a version in, even temporarily. If not, keep a backup copy of the file. One day you might thank me for this advice…Winking smile

Thursday, September 29, 2011

Where are my tables (stored)?

Did you know that, when you create a native datasource in LightSwitch managing tables (entities) from the LightSwitch designer, the corresponding schema along with the data manipulated while debugging are stored in a SQL server database file set found in <ProjectName>\Bin\Data?
These database files are attached to the local instance of SQL 2008 Express. Visual Studio LightSwitch will install one if not found. The SQL server instance must be configured to allow user instances, as by default LightSwitch will attach the aforementioned files as a user instance. Along with your schema, default ASP.NET security schema is also found there.
The connection string compacting all the above can be found in the web.config file of the ServerGenerated project. If you don’t know what or where is this don’t worry we will talk about it in a next post. Just go ctrl+shift+F enter _IntrinsicData as the string to find and search in the entire solution. Please don’t touch. Generated, you know…Winking smile

Wednesday, September 28, 2011

Learn

Did you know you can find LightSwitch self-training resources in places like:
LightSwitch Team Blog
LightSwitch Developer Center
LightSwitch Help Website
Open Light Group
LightSwitch Central
And here you can find a list of many, many more LightSwitch related links.
One thing is for sure, LightSwitch is worth learning Winking smile