Showing posts with label Intermediate. Show all posts
Showing posts with label Intermediate. Show all posts

Tuesday, February 5, 2013

Can I delete this?

In a previous post I suggested a way to override default LightSwitch add/edit behavior. In this post I will suggest an override to default delete behavior.
It has happened many times to delete entries, only to get an error message, when trying to save, informing me about reference constraints being violated and the action cannot be completed. This is not much of problem when you try to delete one record (apart from the fact this message is ugly and not one that I would allow my end users to deal with, for that matter). But when trying to delete many records you have no clue which was the one (or more) record(s) that cannot be deleted. In this case all you can do is delete-save until you find the record that cannot be deleted. And when you find it, you have to refresh your screen or undo the changes of the current record (a future article will suggest a way to do this).
What I needed was a good generic way to be able to set Delete_CanExecute result. This is my suggestion using (what else) extension methods, interfaces (Yann will love me for this Smile) and an attribute.
First the interface to help decide if an instance can be deleted or not:
public interface IDependencyCheck : IEntityObject
{
  bool CanDelete { get; }
}



Quite simple you must admit. Keep in mind interfaces you want to use in your common project have to be accessible both by Server and Client project also. If someone here thinks of EntityName_CanDelete, someone forgets that it is a server side hook.

Now an attribute to help us decide which of the dependencies an entity might have are strong ones, meaning that the referential integrity of the database or your business logic if you don’t use database constraints, would not allow an instance to be deleted.
[AttributeUsage(AttributeTargets.Class)]
public class StrongDependencyAttribute : Attribute
{
  public StrongDependencyAttribute(string dependencies) {
    this.dependencies = dependencies.ToStringArray();
  }

  public string[] Dependencies {
    get { return dependencies; }
  }

  private readonly string[] dependencies;
}

This attribute takes a list of strong reference property names as comma delimited string (or whatever delimiter you like for that matter) using these simple extensions:
public static string[] ToStringArray(this string strings) {
   return strings.ToStringArray(',');
}

public static string[] ToStringArray(this string strings, char delimiter) {
   return (from string item in strings.Split(new char[] { delimiter }, StringSplitOptions.RemoveEmptyEntries)
               select item.Trim()).ToArray();
}



If you want to use another delimiter just replace
this.dependencies = dependencies.ToStringArray();



in the constructor with (for example):
this.dependencies = dependencies.ToStringArray(';');

Or if you want, you can have one instance of the attribute for each property you want to check and avoid delimited strings altogether. Plenty of choices…Smile.

Keep in mind that if you declare no instance of this attribute but you implement IDependencyCheck then ALL dependencies will be considered as strong ones and checked for integrity.

This attribute needs to be accessible by the Common project only.

Now, all that said, there are two extension methods that will help us do the job.

The first one needs to be accessible by the Client project only:
public static bool CanDeleteSelection(this IScreenObject screen, string collectionName) {
   if (!screen.HasSelection(collectionName))
     return false;
   IVisualCollection collection = screen.Details.Properties[collectionName].Value as IVisualCollection;
   if (collection.SelectedItem is IDependencyCheck)
     return (collection.SelectedItem as IDependencyCheck).CanDelete;
   return true;
}



Please note I am using IScreenObject.HasSelection extension that has already been introduced in a previous post. That’s why I am not checking if the cast to IVisualCollection is successful (not null).

The second one has to be accessible by the Common project only:
    public static bool CanDelete(this IEntityObject entity) {
      IEnumerable<IEntityCollectionProperty> collectionProperties = 
        entity.Details.Properties.All()
        .Where(p => p.GetType().GetInterfaces()
          .Where(t => t.Name.Equals("IEntityCollectionProperty"))
          .FirstOrDefault() != null)
        .Cast<IEntityCollectionProperty>();
      if (collectionProperties == null)
        return true;
      List<string> strongDependencies = new List<string>();
      IEnumerable<StrongDependencyAttribute> dependencies = 
        entity.GetType()
        .GetCustomAttributes(typeof(StrongDependencyAttribute), false)
        .Cast<StrongDependencyAttribute>();
      foreach (StrongDependencyAttribute dependency in dependencies)
        strongDependencies.AddRange(dependency.Dependencies);
      bool hasDependencies = strongDependencies.FirstOrDefault() != null;
      bool canDelete = true;
      foreach (IEntityCollectionProperty property in collectionProperties) {
        if (hasDependencies &&strongDependencies.FirstOrDefault(d => d.Equals(property.Name)) == null)
          continue;
        IEnumerable value = entity.GetType()
          .GetProperty(string.Format("{0}Query", property.Name))
          .GetValue(entity, null) as IEnumerable;
        try {
          if (value != null && value.GetEnumerator().MoveNext()) {
            canDelete = false;
            break;
          }
        }
        catch {
          continue;
        }
      }
      return canDelete;
    }



Although it’s obvious at first glance what the code does Hot smile, I will give brief explanation:

If there is not a StrongDependencyAtttibute defined for the entity then all reference properties are checked and if at least one has members then the entity cannot be deleted. If a StrongDependencyAtttibute is defined for the entity then only reference properties included in the attribute are checked. That’s all…

If you manage to read the code (I am not very proud about the absence of comments) you will notice that only one-to-many and many-to-many references are handled. In my world one-to-one references mean inheritance and in this case both objects should be deleted. But what if the base object can be deleted (has no direct references) and the derived object has? Again in my world, if you are trying to delete the base object you are already doing it wrong! Anyway if someone lives in a world other than mine (I am very democratic guy Be right back) and wants to support one-to-one relations all he/she has to do is find where IEntityCollectionProperty definition is and look for the respective property type (I believe it is IEntityReferenceProperty but I am not quite sure).

And for the end an example so that anyone can see what all of the above end up to:

Suppose you have a Customer entity. And this Customer entity has a collection of Orders. The property of the Customer entity that holds these orders is called CustomerOrders. In your Datasource you right-click Customer entity and select View Table Code. A partial class implementation file is created (if it does not already exist). Modify the definition of you class as follows:
[StrongDependency("CustomerOrders")]
public partial class Customer : IDependencyCheck {
...

  #region IDependencyCheck members 
  public bool CanDelete {
    get { return this.CanDelete(); }
  }
  #endregion IDependencyCheck members
}



Remember to reference (using) the namespace where your extension method (CanDelete) is declared.

Please note that IDependencyCheck gives you the potential to write whatever else hardcoded (or not) check you want in your CanDelete property implementation. In the code above I just call the extension method I introduced earlier. But you can do whatever you want. You can even skip the dependencies mechanism suggested altogether. The client side extension will still work.

So in the screen that you have your list of Customers right click the Delete command of the list or grid and in the CustomersDelete_CanExecute just write:
partial void CustomersDelete_CanExecute(ref bool result){
  result = this.CanDeleteSelection("Customers");
}



As partial implementation of Execute write:
partial void CustomersDelete_Execute(){
  this.Customers.DeleteSelected();
}



I know some of you have already noticed the overhead of potentially loading the dependent objects the first time you select an item of your list or grid. I cannot argue with that, except for the fact that my approach is suggested for intranet implementations (I am not sure I would do something like that over the web) and the fact that the time under these circumstances is an acceptable price to pay in order to avoid the annoying referential integrity message. At least in my world Smile

Wednesday, November 7, 2012

De-fault Screens

If you have tried implementing something that required a mechanism more complex than the default one provided by LightSwitch regarding default screen selection, you already are familiar with the limitations.
For the ones that don’t get what I mean, a very common example is open the details screen of an object from a list containing items from a view (database view) that include the id of the original object. Imagine you have a Customer entity and a CustomerInfo entity that comes from a database view bringing aggregated data of the customer from various tables. Selecting and editing the CustomerInfo you want to edit the Customer not the CustomerInfo.
The above is only one fast example. Another would be having Add/Edit Screens i.e. screens that can handle both create or edit an existing object. In any case if you need to modify the default signature of a default screen (adding an extra parameter for example) causes this screen to be unselected as default screen because LightSwitch mechanism for default screens cannot handle it.
Going back to the Customer/CustomerInfo example, I have come across at least a couple of posts in threads trying to find a way to “override” the default click behavior of links in collections. In our example clicking on the link of the customer’s name (for example) will open a default screen for CustomerInfo.
So, one easy solution is creating a default screen for CustomerInfo where upon load you will open the Customers default screen passing the id of the customer and close the current one. But how do you handle allowing only one instance of a details screen per object? Or all other issues that might come come up? (Imagine you have more than one view entities for the Customer entity).
Anyway, this is my approach at solving this issue, that works fine for me in a big project whose development runs for almost a year now (and by the way is the reason for not posting very often –understatement of the year- here lately):
Reintroducing the ShowDefaultScreen method of the Application in the Client project along with an interface defined and implemented by all screens that need to be involved.
  • This is the interface definition:
public interface IDefaultScreen : IScreenObject
{
    bool Shows(IEntityObject instance);
    IEntityObject Object { get; }
}




  • This is the code in Application.cs:
public new void ShowDefaultScreen(IEntityObject instance) {
      this.ShowOrFocusDefaultScreen(instance);
}

public void ShowOrFocusDefaultScreen(IEntityObject entity) {
  foreach (IActiveScreen activeScreen in this.ActiveScreens) {
    if ((activeScreen.Screen is IDefaultScreen) &&
        (activeScreen.Screen as IDefaultScreen).Shows(entity)) {
          activeScreen.Activate();
          return;
        }
      }
  entity.Details.Dispatcher.BeginInvoke(() => {
    if (!HandleEntityDefaultScreen(entity))
      base.ShowDefaultScreen(entity);
  });
}

private bool HandleEntityDefaultScreen(IEntityObject entity) {
  switch (entity.GetType().Name) {
    case "CustomerInfo": {
        this.ShowEditCustomer((entity as CustomerInfo).Id);
        return true;
      }
      .
      .
      .
  }
  return false;
}
In the code displayed above the implementation in HandleEntityDefaultScreen code is just to demonstrate the concept. The ellipsis below the first case implies you can write whatever is required by your application.


  • And finally this is the code from the Customer details screen that implements IDefaultScreen:
public partial class EditCustomer : IDefaultScreen
{
   .
   .
   .
  #region IDefaultScreen Members
  public bool Shows(IEntityObject instance) {
    return (instance is CustomerInfo) &&
           (instance as CustomerInfo).Id.Equals(this.CustomerProperty.Id);
  }

  public IEntityObject Object {
    get { return this.CustomerProperty; }
  }
  #endregion
}

The careful reader will notice that the IEntityObject Object { get; } property exposed by IDefaultScreen is not used in the sample code. I ported the code exactly as I use it in my projects (apart from the changes made to demonstrate the Customer/CustomerInfo paradigm) where this property is used for a different purpose. You can either remove it or find a good use for it Winking smile.

Wednesday, July 11, 2012

Simple Extension Methods (part 3)

One very common task when one is implementing the business logic in Common project is writing custom PropertyName_Changed partial methods.
This “approach” has an undesired “side-effect” when the property is an entity property (as compared to screen properties). The property changes many times during the lifetime of the object. While loading, while deleting etc., whereas what we want to implement is handle the “actual” property changes caused either by the user or by some other piece of business logic.
I found myself debugging code that shouldn’t be executing (according to my logic, obviously LS had another opinion) before ending up writing a small extension method to use in all PropertyName_Changed partial methods. I don’t claim this method will help you avoid ALL unwanted business logic code execution, but covers most of the cases. I would be glad to read any comments improving it in a generic way.
Here is the code of the extension method:
public static bool IgnorePropertyChange(this IEntityObject entity) {
  return entity.Details.EntityState == EntityState.Unchanged ||
         entity.Details.EntityState == EntityState.Discarded ||
         entity.Details.EntityState == EntityState.Deleted;
}




And here how all my property changed partial implementations for entity properties look like
partial void ScheduledEndDate_Changed() {
  if (this.IgnorePropertyChange())
    return;
  .
  .
  .
}



This looks (and is) simple but the concept, alone, of “unwanted” code execution is important and should be taken good care of. If not using this extension method any other way one may like Winking smile.

Friday, June 29, 2012

Simple Extension Methods (part 2)

In the previous post I presented an extension method used mostly for overriding the edit and delete commands of a collection. One may ask “why do I want to do this?”. Apart from any other requirements/business logic dependent reason one might want to implement, for me there is one simple yet important reason: I don’t like at all (to be kind) the default add/edit modal windows when adding or editing an entry. It’s not a coincidence that the FIRST sample I wrote for LightSwitch and posted in the Samples of msdn.com/lightswitch was a set of extension methods and contracts to easily replace standard modal windows with custom ones.
Most of the times when I have an editable grid screen, selecting Add or Edit I DON’T want the modal window to pop-up, I just want to edit in the grid. Or in list and details screen I want to edit the new or existing entry in the detail part of the screen.
This is the main reason I most of the times override the default Add/Edit command behavior. And for this reason I created and use the next two extension methods:
public static void AddFocus<T>(this VisualCollection<T> collection, string focusControl, bool inCollection)
      where T : class, IEntityObject {
      collection.AddNew();
      collection.EditFocus(focusControl, inCollection);
    }

    public static void EditFocus<T>(this VisualCollection<T> collection, string focusControl, bool inCollection)
      where T : class, IEntityObject {
      if (focusControl != null) {
        try {
          IContentItemProxy control = null;
          if (inCollection)
            control = collection.Screen.FindControlInCollection(focusControl, collection.SelectedItem);
          else
            control = collection.Screen.FindControl(focusControl);
          Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() => {
            try {
              control.Focus();
            }
            catch {
              collection.EditSelected();
            }
          });
        }
        catch {
          if (collection.HasSelection())
            collection.EditSelected();
        }
      }
    }





So what you have to do in your MyCollectionAddAndEditNew_Execute partial method is write something like:
MyCollection.AddFocus("TheNameOfTheControlYouWantToFocus", true);



or for MyCollectionEdit_Execute partial method:
MyCollection.EditFocus("TheNameOfTheControlYouWantToFocus", true);

if you have a list detail screen the same code applies but with inCollection = false.

One could implement one method for collections and one for details. Also notice where constraints applied to T generic parameter. The class constraint is required for declaring VisualCollection<T>. The IEntityObject constraint is required so that we avoid the arbitrary casting of collection.SelectedItem to IEntityObject so as to be passed to FindControlInCollection as second parameter.

Notice that in the extension methods I don’t check if the control name exists. I just use try catch. On error (if the control name is not valid) I choose to fall-back to the default behavior. You can change this without any intellectual rights being violated Smile.

Tuesday, June 26, 2012

Simple Extension Methods (part 1)

As soon as I started writing LightSwitch applications I noticed that many times I was repeating the same code over and over for trivial tasks. So after all this time I have collected a number of extension methods that I widely use in my apps.
For me reusing code is a must and although the implementation of LS (IMHO) does not provide for this out of the box the underlying framework is ideal for writing extension classes and methods that are a major step towards code reusability. If you have downloaded any of my samples from msdn or have seen my Application Logo post, you already suspect I am an “extension method fanatic”.
So I will present a small series (I don’t know how small) of posts with extension methods from my Base.LightSwitch.Client library.
The first method is one of the first (if not the first one) extension methods I wrote. As soon as you want to override the code for default commands like Edit and Delete for a collection (let’s name it MyCollection) you have to write something like that:
partial  void MyCollectionDelete_CanExecute(ref bool result){
  if (this.MyCollection is null || this.MyCollection.SelectedItem == null)
    result = false;
  else
    result = true;
}

This is the minimum code (it can be written more elegantly I know but this is the concept) you need to write. I don’t take into account the permissions issue.

A similar chunk of code has to be written for Edit.

Isn’t the code listed below easier to read:
partial  void MyCollectionDelete_CanExecute(ref bool result){
  result = this.HasSelection("MyCollection");
}
It’s not only easier to read but is less error prone than the original. Plus you can inject any security logic in this HasSelection method.
And this is the code:
public static bool HasSelection(this IScreenObject screen, string collectionName) {
  if (!screen.Details.Properties.Contains(collectionName))
    return false;
  IVisualCollection collection =
    screen.Details.Properties[collectionName].Value as IVisualCollection;
  return collection != null &&
         collection.SelectedItem != null &&

         (collection.SelectedItem as IEntityObject).Details.EntityState != EntityState.Deleted;
}
For the ones that dislike using string property names I can suggest this version :
public static bool HasSelection<T>(this VisualCollection<T> collection) where T : class, IEntityObject {
  return collection != null &&
         collection.SelectedItem != nul &&
         collection.SelectedItem.Details.EntityState != EntityState.Deleted;
}


This version is more concrete is generic and also does not have to do the (out of thin air) conversion of SelectedItem to IEntityObject. If you use this version though you have to change your partial method as you cannot extend null:
partial void MyCollectionDelete_CanExecute(ref bool result){
  result = MyCollection!= null && MyCollection.HasSelection();
}
The choice is yours…Smile

Tuesday, February 7, 2012

Re-Views

In previous posts I made reference to views (DB or RIA) as an alternative (amongst other well-known potentials of views) to search and sort against fields that would normally be relations (lookups or however you want to call them).
From the very beginning I had an issue with SQL Server views imported to LS. LightSwitch had a very strange way to define the primary keys of the views. These “inferred” primary keys are most of the time very complex combined keys. And this is not an issue actually until you decide to add a relationship between this view (which 99% of the times has only one field as actual primary key) and another table. Then you realize this, otherwise benign, complex primary key is an issue (to say the least).
It was only recently, in this thread, after Yann Duran’s suggested reading (always to the rescue and always having something useful to contribute), that I managed to both understand how LS “infers” the Primary Key for a View and realize how one can “force” a primary key.
The bottom line is that LS decides that all not-nullable fields will be part of the inferred primary key. Not very inspired but I must admit I cannot think of anything better. So, how one can force the primary key one wants? The way is re-introducing all you not-nullable, non-key fields by cast/convert to the same data-type (or another one if needed). This way the definition of the “table”/”view” imported by LS contains all, originally not nullable fields, as nullable.
Very short example. Imagine Table Person as
Id int not null, PK
LastName nvarchar(50) not null,
FirstName nvarchar(50) null,
.
.
.
Your view’s SQL would be
select Id, CONVERT(nvarchar(50), LastName) as LastName, FirstName
from Person
Simple, dummy example just to display what I mean.
I feel I am re-inventing the wheel as this information was already out there, but in Greece we say “Επανάληψη μήτηρ μαθήσεως” or “Repetition is the mother of Learning” or something like that. Looks like we never learned much from this anyways…

P.S. After Yann's suggestion I have to note that actually this inferred primary key mechanism is Entity Framwork's native and not LightSwitch own behaviour. Although I had that in my mind I didn't make it clear here. I apologize for any missunderstanding and I thank Yann once more for the comment.

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

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