Friday, July 13, 2012

Just Visiting or (not so) Simple Extension Methods (part 4)

One of my favorite design patterns since the age of c++ is the Visitor Pattern. I will not explain here what the visitor pattern is. But, if you know how to use the design pattern this is a post worth reading.
One may ask what the visitor pattern has to do with LightSwitch. Well, it doesn’t! I mean not exclusively. But the code below provides a full visitor pattern implementation background that can also be used in LS. Also, a part of the implementation is ideal for LS, since one of the challenges I had to face, when trying to widely use the visitor pattern, was make it work for “sealed” classes, classes that were not written by me and could not easily fit to my –reflection based- visitor pattern implementation. To solve this the best thing I could think of was “wrapping”. And working with LS, most of the classes (apart from the ones that belong to the domain/datasource) are actually “sealed” in the way described above.(I have to note here that this reflection-based implementation is a revision of an implementation I found (if I recall correct) in CodeProject).
First the two basic interfaces that have to be defined:
The IVisitor interface that has to be implemented by the “worker” (or helper to follow the VB-oriented naming of the LS Team Sarcastic smile) class.
public interface IVisitor
{
  void VisitDefault(IVisitorTarget source);
}



Then the IVisitorTarget interface (implied above) that has to be implemented by the class to be “consumed/visited” by the Visitor.
public interface IVisitorTarget
{
  void Accept(IVisitor visitor);
}



Ok, I know, nothing much up to now. But as I say “The longest journey starts with the first step”…(yes I am an old Chinese philosopher)

To have your visitor pattern in place you need an extension method to do the trick:
public static bool ConcreteVisit(this IVisitorTarget target, IVisitor visitor) {
  Type[] types = new Type[] { target.GetType() };
  MethodInfo mi = visitor.GetType().GetMethod("Visit", types);

  if (mi == null)
    return false;

  mi.Invoke(visitor, new object[] { target });
  return true;
}

Now that these pieces are in place let’s say we have a class called DisplayNameBuilder that implements the IVisitor interface. Also, let’s say we have a Customer entity in our datasource and we want it to implement the IVisitorTarget interface. All we have to do is open Customer entity in the designer, click Write Code and change the class declaration to:
public partial class Model : IVisitorTarget



make sure you are using the namespace of the class where the above extension method is implemented and implement the IVisitorTarget interface like this:
#region IVisitorTarget Members
public void Accept(IVisitor visitor) {
  if (!this.ConcreteVisit(visitor))
    visitor.VisitDefault(this);
}
#endregion



Also this is a sample implementation of the DisplayNameBuilder class:
public class DisplayNameBuilder : IVisitor
{
  public string Name{
    get;
    private set;
  }

  public void VisitDefault(IVisitorTarget visitorTarget){
    Name = visitorTarget.ToString();
  }

  public void Visit(Customer visitorTarget){
    Name = string.Format("{0}{1}{2}", visitorTarget.FirstName, string.IsNullOrWhiteSpace(visitorTarget.FirstName) ? "", " ", visitorTarget.LastName);
  }
}



In the above code please note these:


  1. The code was written in Live Writer as it’s demo code, so maybe it does not compile as is.Embarrassed smile

  2. The customer is implied to have a nullable FirstName property and a not nullable LastName (which I believe it’s a fair assumption and I agree with me).

  3. The implementation, as obvious, is domain aware as it knows what Customer is. This implies that the ideal place for this class to live is in the Common project.

Now lets say you create a calculated string field in Customer entity called hmmmmm… DisplayName (surprised? It’s a gift I have regarding giving original namesSmile with tongue out). This would be the code that would implement the calculation of DisplayName property:
partial void DisplayName_Compute(ref string result) {
  DisplayNameBuilder builder = new DisplayNameBuilder();
  this.Accept(builder);
  result = builder.Name;
}

I HAVE to stress one more time that the code is for demonstration purposes only. It’s not just you, it IS too much fuss for nothing.

Ok, now it should be easier to understand the problem of using the visitor pattern with pre-defined classes. You cannot add the IVisitorTarget behavior to most of the classes, automatically generated by LS.

So this is the solution to the problem.
public class IVisitorWrapper<TObjectType> : IVisitorTarget
{
  public TObjectType Content {
    get;
    set;
  }

  #region IVisitorTarget Members
  public void Accept(IVisitor visitor) {
    if (!this.ConcreteVisit(this, visitor))
      if (!this.VisitWrapper(this, visitor))
        visitor.VisitDefault(this);
  }
  #endregion
}




This is a wrapper class (one could say it is an IVisitorTarget decorator). If you are still with me and you keep on reading the code you have already noticed that VisitWrapper extension method is not yet defined, so this is it:
public static bool VisitWrapper<TObjectType>(this IVisitorWrapper<TObjectType> wrapper, IVisitor visitor) {
  Type[] types = new Type[] { typeof(TObjectType) };
  MethodInfo mi = visitor.GetType().GetMethod("Visit", types);

  if (mi == null)
    return false;

  mi.Invoke(visitor, new object[] { wrapper.Content });
  return true;
}



Now you can wrap any type of object and use the DisplayNameBuilder to build it’s display name. Also (as –I hope- you guessed) you have to implement the respective Visit method in DisplayNameBuilder in order not go get the type name back as Name.

Well, as Porky says: That’s all Folks Smile. I hope that except for exhausting it was also interesting.

Wednesday, July 11, 2012

Application Logo (tailored on customer demand)

This is the most recent comment in the Application Logo Sample post:
“Hi Kostas,
I wanted to find out if there is a way of opening an active screen as soon as I click on the logo. I have tried but my attempt was in vain. If it is possible, could you please help me out?
Thanks,
Darryn”

My first reaction was to ask for details (typical way of buying time Smile). But then I though I could do the changes required and post a new article. So simply put, this is the answer I propose to Darryn:
public static void AddLogo(this Microsoft.LightSwitch.Client.IClientApplication application, System.Windows.HorizontalAlignment alignment, string screenName) {
  Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() => { LogoPlacement.AddLogo(application, System.Windows.Application.Current.RootVisual, alignment, screenName); });
}


private static class LogoPlacement
{
  internal static void AddLogo(Microsoft.LightSwitch.Client.IClientApplication application, UIElement element, System.Windows.HorizontalAlignment alignment, string screenName) {
    if (rcb != null) return;

    for (int i = 0; i < System.Windows.Media.VisualTreeHelper.GetChildrenCount(element); i++) {
      if (rcb != null)
        return;
      UIElement child = (UIElement)System.Windows.Media.VisualTreeHelper.GetChild(element, i);
      AddLogo(application, child, alignment, screenName);
    }
    if (element is Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard.RibbonCommandBar) {
      rcb = element as Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard.RibbonCommandBar;
      Image myImage = new Image() {
        Stretch = System.Windows.Media.Stretch.Uniform,
        Margin = new Thickness(2, 8, 14, 8),
        HorizontalAlignment = alignment,
        Cursor = System.Windows.Input.Cursors.Hand
      };
      myImage.SetValue(ComponentViewModelService.ViewModelNameProperty, "Default.LogoViewModel");
      myImage.SetBinding(Image.SourceProperty, new System.Windows.Data.Binding { Path = new PropertyPath("Logo") });
      if (!string.IsNullOrWhiteSpace(screenName))
        myImage.MouseLeftButtonUp += (s, e) => { application.Details.Dispatcher.BeginInvoke(() => application.Details.Methods[string.Format("Show{0}", screenName)].CreateInvocation().Execute()); };
      myImage.SizeChanged += (s, e) => {
        double left = (s as Image).HorizontalAlignment == HorizontalAlignment.Left ? e.NewSize.Width + 10.0 : 0.0;
        double right = (s as Image).HorizontalAlignment == HorizontalAlignment.Right ? e.NewSize.Width + 10.0 : 0.0;
        rcb.Padding = new Thickness(left, 0, right, 0);
      };
      ((Grid)rcb.Parent).Children.Add(myImage);
    }
  }




With bold I have marked the additions/changes I had to make to accommodate Darryn’s request.
I hope Darryn is happy Smile with tongue out.

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

Friday, June 22, 2012

RIAlity Issues

Recently I had to face a very frustrating issue regarding the integration of a RIA Service as a LightSwitch Datasource. I tried to find references for it in the web. I did. But none of them (at least the ones I managed to find) didn’t seem to match my case. So after solving my issue I thought sharing was a good idea…
After having implemented and tested my RIA service using a small Silverlight application I decided to add a datasource and use it. Which I did. Focusing at the part of the RIA service that caused the problem, I had a class called ImageAttachment and 2 queries exposing it. Below you can see the initial code:
   1:      [Query(IsDefault = true)]
   2:      public IQueryable<ImageAttachment> GetImageAttachments() {
   3:        return new List<ImageAttachment>().AsQueryable();
   4:      }
   5:   
   6:      public IQueryable<ImageAttachment> GetFolderItemImageAttachments(Guid? providerId, string folderId, string mailItemId) {
   7:        if (!providerId.HasValue || folderId == null || mailItemId == null)
   8:          return GetImageAttachments();
   9:        return GetAttachments(providerId.Value, folderId, mailItemId);
  10:      }



Importing the RIA Service GetFolderItemImageAttachments was properly imported as an optional query for ImageAttachment.

image

I added an ImageAttachment visual collection in a screen fetching results from GetFolderItemImageAttachments query. Everything worked smoothly. But when the time came to load the visual collection (i.e. run the query) I got an exception I hadn’t come across before neither as a LS developer nor as a Silverlight one:

Load operation failed for query ‘GetFolderItemImageAttachments’.  The remote server returned an error: NotFound.

The behavior was very strange. Although the query was recognized and imported from LS for some reason at runtime it looked like the method was not found. I placed a breakpoint at the method and it didn’t hit. The method was never called. Before doing this I was sure it was some bug of mine in the implementation that caused the RIA service to throw this generic exception. But no! The execution never reached the web method. It was then that I decided to “google” it. Looked like it was a RIA Services+LightSwitch(?) issue. All references where either not appropriate in my case or had no effect. Then I did what I usually do when I have problem I cannot solve: I scrolled to the part of code listed above and started to just stare at the code waiting for an answer. And I came to me! Why not make sure the query method IS a query? So what I did was just add the QueryAttribute to my method with no parameters:

   1:      [Query(IsDefault = true)]
   2:      public IQueryable<ImageAttachment> GetImageAttachments() {
   3:        return new List<ImageAttachment>().AsQueryable();
   4:      }
   5:   
   6:      [Query]
   7:      public IQueryable<ImageAttachment> GetFolderItemImageAttachments(Guid? providerId, string folderId, string mailItemId) {
   8:        if (!providerId.HasValue || folderId == null || mailItemId == null)
   9:          return GetImageAttachments();
  10:        return GetAttachments(providerId.Value, folderId, mailItemId);
  11:      }




I thought that if it didn’t solve the problem I surely would not cause a new one. It IS a query method after all. Why let LS infer it? And it worked.

I am quite sure I was lucky. I mean, the query was recognized either way. I cannot explain what exactly was the bug the QueryAttribute fixed. To stress my point more, I have to admit that went back to the RIA Service and I removed the attribute. Still worked! Like a deadlock resolved. Maybe only LightSwitch Team can explain. Anyhow I thought of sharing in case anyone else runs into something like this.Smile

Monday, June 11, 2012

You Are I.

Finding my application’s URI address either in deployment or development/debugging environment has been an issue I had to face in my early LightSwitch days. Although not a LightSwitch issue, but rather a Siverlight/ASP.NET one, I thought that sharing the 2 lines of code I have ended up using to discover the URI (along with the port, most important for debugging and/or standalone deployments) might be useful.
First the client. The first and easy approach was extracting the URI and port from System.Windows.Browser.HtmlPage.Document.DocumentUri. Nice! Not really. This only works for web and NOT OOB (Out of Browser) or Desktop according to LS naming, applications. System.Windows.Browser namespace is in general not available in ΟΟΒ applications.
The way I ended up adopting is accessing System.Windows.Application.Current.Host.Source.AbsoluteUri. Ok, I know it’s WPF/Silverlight way (System.Windows… I mean) but my experience says that a similar approach will be available even if HTML 5 is the next (not too soon I expect) output of LS.
Then the server. Here things are simpler and for as long as the server part of a LS application remains a Web Service the path will always be the same: HttpContext.Current.Request.Headers["HOST"].
That’s it! Short but juicy (I hope Smile).