Client Databases for Silverlight

When comes the time to use Silverlight out of browser functionality, we may have to face the fact that Silverlight might be used without an internet connection. In this particular case, the application must implement a local cache.

I have found some very interesting database solution available for Silverlight.

siaqodb (in beta when this post was published)

This database is using LINQ natively to retrieve the data which is stored in the isolated storage on the client machine.

var p = new Product { Name = "Pencil", Price = 0.25 };

db.StoreObject(product);

var query = from Product p in db
            where p.Name == "Pencil"
            select p;

http://siaqodb.com/

Silverlight Database (in beta when this post was published)

Again, this database is using the isolated storage to persist locally the offline data.

var db = Database.CreateDatabase("test");
db.CreateTable<Person>();

var person = new Person{ FirstName = "John", LastName = "Doe" };
db.Table<Person>().Add(person);

var q = from p in db.Table<Person>()
        where p.LastName == "Doe"
        select p;

http://silverdb.codeplex.com/

Others

db4o : They are working on a Silverlight port.
EffiProzSL : A port of the EffiProz database.
Perst : A port from Java.

Experimentations

Google gears and silverlight
C#-SQLite running in Silverlight

Happy new year!

WCF RIA Services without code using a TriggerAction

When you drop a WCF RIA service data source in the visual studio 2010 Beta 2, you will see that it generates for you a load button and assign it an event handler that call Load on the ria data source.

I don’t know for you but I find easier to use a TriggerAction than having to write the same code again and again.

In this post, I will discuss some TriggerAction that I have implemented and helps me write RIA application faster.

LoadAction

Loading data using a data source in RIA services is very simple. You only have to call Load. Why not ease that by making it available in Microsoft Expression Blend 3 using a TriggerAction.

Here is the implementation of the LoadAction that targets a DomainDataSource.

public class LoadAction : TargetedTriggerAction<DomainDataSource>
{
    protected override void Invoke(object parameter)
    {
        var target = Target;
        if (target != null && !target.IsLoadingData)
            target.Load();
    }
}

Wow! That was easy. 3 lines of code and we have our first action. Have a try in Blend and you will see that it really helps.

SubmitChangesAction

Submit data is also very simple. Here is how to do it using a TriggerAction:

public class SubmitChangesAction : TargetedTriggerAction<DomainDataSource>
{
    protected override void Invoke(object parameter)
    {
        var target = Target;
        if (target != null)
            target.SubmitChanges();
    }
}

NavigateAction

Ok, this one is a bit harder to implement but will helps you. To navigate in Silverlight, we need an instance of the NavigationService and call the Navigate method. Again, this can be simplified.

Create a TriggerAction to be attached to the Page since this is where we can have an instance of the NavigationService. We will add a property called PageUri which is the page to navigate to when the action is called:

public class NavigateAction : TriggerAction<Page>
{
   #region PageUri DependencyProperty
   public string PageUri
   {
      get { return (string)GetValue(PageUriProperty); }
      set { SetValue(PageUriProperty, value); }
   }

   public static readonly DependencyProperty PageUriProperty = DependencyProperty.Register
   (
      "PageUri",
      typeof(string),
      typeof(NavigateAction),
      new PropertyMetadata(null)
   );
}

protected override void Invoke(object parameter)
{
   var pageUri = PageUri;

   if (string.IsNullOrEmtpy(pageUri))
      return;

   var page = AssociatedObject;
   var uri = new Uri(pageUri, UriKind.RelativeOrAbsolute);
   var service = page.NavigationService;

   if (service != null)
      service.Navigate(uri);
}

NavigateAction with QueryString parameters

Good, we have a working NavigateAction. I think we can do much better. How about support for passing parameters in the query string. Here is the new implementation:

[ContentProperty("Parameters")]
public sealed class NavigateAction : TriggerAction<Page>
{
   public NavigateAction()
   {
      Parameters = new ObservableCollection<NavigateActionParameter>();
   }

   #region Methods
   private Uri CreateUri()
   {
      var s = PageUri;

      if (string.IsNullOrEmpty(s))
         return null;

      var c = s.Contains("?") ? '&' : '?';

      for (var i = 0; i < Parameters.Count; i++)
      {
         var parameter = Parameters[i];
         if (parameter == null)
            continue;

         var value = parameter.Value;
         if (value == null)
            continue;

         s += c + parameter.ParameterName + '=' + Uri.EscapeDataString(value);
         c = '&';
      }

      return new Uri(s, UriKind.RelativeOrAbsolute);
   }

   protected override void Invoke(object parameter)
   {
      var page = AssociatedObject;
      var uri = CreateUri();
      var service = page.NavigationService;

      if (uri != null && service != null)
         service.Navigate(uri);
   }
   #endregion

   #region Properties
   #region PageUri DependencyProperty
   public string PageUri
   {
      get { return (string)GetValue(PageUriProperty); }
      set { SetValue(PageUriProperty, value); }
   }

   public static readonly DependencyProperty PageUriProperty = DependencyProperty.Register
   (
      "PageUri",
      typeof(string),
      typeof(NavigateAction),
      new PropertyMetadata(null)
   );
   #endregion
   public ObservableCollection<NavigateActionParameter> Parameters { get; private set; }
   #endregion
}

public sealed class NavigateActionParameter : DependencyObject
{
   #region Properties
   public string ParameterName { get; set; }

   #region Value DependencyProperty
   public string Value
   {
      get { return (string)GetValue(ValueProperty); }
      set { SetValue(ValueProperty, value); }
   }

   public static readonly DependencyProperty ValueProperty = DependencyProperty.Register
   (
      "Value",
      typeof(string),
      typeof(NavigateActionParameter),
      new PropertyMetadata(null)
   );
   #endregion
   #endregion
}

You can now use the NavigateAction and add parameters in the Query String in Blend without using code. Here is a sample

<l:NavigateAction PageUri="/BacklogItemView?Action=Update">
   <l:NavigateActionParameter ParameterName="Id" Value="{Binding Path=SelectedItem.Id, ElementName=dataGrid1}"/>
</l:NavigateAction>

This will pass a parameter named Id in the Query String.

Happy programming!

Combining Command and TriggerAction In Silverlight

Since Blend 3, we can create a TriggerAction to implement various redundant things. Even redundant business logic can be implemented as TriggerAction.

Commands on the other side is great way to notify controls that an action can be executed. A command can also be used on more than one control.

In this post, I will discuss a way to create command and bind it to an action so the action is invoked when a command is executed. After that, you will be able to use Blend 3 to create a command in resources and bind it to an action.

A reusable command

We will start by implementing a command that have an event Executing. This event is going to occur when the method Execute is called.

public class EventCommand : DependencyObject, ICommand
{
    #region Methods
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        if (Executing != null)
            Executing(parameter);
    }
    #endregion

    #region Events
    public event EventHandler CanExecuteChanged;
    public event ExecuteEventHandler Executing;
    #endregion
}

public delegate void ExecuteEventHandler(object parameter);

A Trigger to invoke the action

We need a class that will handle the executing event of the EventCommand and fire the action. We call this class a CommandTrigger. Here is the implementation of this trigger:

public class CommandTrigger : TriggerBase<DependencyObject>
{
    #region Methods
    private void HandleCommandExecuting(object parameter)
    {
        InvokeActions(parameter);
    }
    #endregion

    #region Properties
    #region Command DependencyProperty
    public EventCommand Command
    {
        get { return (EventCommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register
    (
        "Command",
        typeof(EventCommand),
        typeof(CommandTrigger),
        new PropertyMetadata(OnCommandChanged)
    );

    private static void OnCommandChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var trigger = (CommandTrigger)o;
        var oldValue = (EventCommand)e.OldValue;
        var newValue = (EventCommand)e.NewValue;

        if (oldValue != null)
            oldValue.Executing -= trigger.HandleCommandExecuting;

        if (newValue != null)
            newValue.Executing += trigger.HandleCommandExecuting;
    }
    #endregion
    #endregion
}

Advantages of this technique:

  • Having a trigger separate the action from the invoker. The action can now be invoked when the control is loaded, on a timer.
  • Having a command helps reuse the same instance of the action and invoke it from anywhere.

Disavantages of this techinique:

  • I did not find a good way of setting the CanExecute property of the command.

Usage

Image you want to remove an element when the user click a button, you can now do it like that:

<Grid>
   <Grid.Resources>
      <local:EventCommand x:Key="RemoveElementCommand"/>
   </Grid.Resources>

   <Button Command="{StaticResource RemoveElementCommand}"
               Content="Remove Element" />

   <ContentControl>
      <i:Interaction.Triggers>
         <local:CommandTrigger Command="{StaticResource RemoveElementCommand}">
            <mi:RemoveElementAction/>
         </local:CommandTrigger>
      </i:Interaction.Triggers>
   </ContentControl>

</Grid>

Happy programming!

Guidelines for working with ADO.Net Entity Framework

I would like to share with you some Guidelines for working with ADO.Net Entity Framework and other Linq flavored Framework.

  • We should enable all the integrity from the database. The validation of the integrity is not provided by the framework. It will be more effective if the database can return the index or the foreign key that is failing. I will need to do some test on this.
  • Don’t add instance properties or methods to the entities. Entities are not like business objects, they are only data container. Also, using instance properties inside entity reduce the easiness to write queries using the linq syntax.

    Ex: Supposed you’ve add the property MyProperty by code to the entity Employee. Now, supposed someone want to query the employee with your property:

    var q = from e in db.Employees
    where e.MyProperty != null
    select e;

    This will throw an exception at runtime because MyProperty cannot be translated to SQL.
  • Consider not putting validation into the model.
  • Don’t put UI stuff in the model. It may seems evident but ...
  • Use an interface over your model. Consider design for testability.

I will probably add more in the future.

Stay tune!

Dany

WeakEventHandler

I came across a problem this week. I was needing a weak delegate to handle a situation where I have a ListBox and I want it to listen to a property changed on a selected ListBoxItem. This situation need to have a weak delegate because if the ListBoxItem is kept referenced, I want to let the ListBox to be garbage collected.

This is how I have implemented the WeakEventHandler. I thought it was a good implementation because it also supports the anonymous methods even if they are closure.

WeakEventHandler

The WeakEventHandler is a thin class inheriting the WeakHandler<T> and provinding a closure delegate in the CreateHandler.

public sealed class WeakEventHandler : WeakHandler<EventHandler>
{
    public WeakEventHandler(EventHandler handler)
        : base(handler)
    {
    }

    protected override EventHandler CreateHandler(WeakReference weakReference)
    {
        return (sender, e) =>
        {
            var h = (EventHandler)weakReference.Target;
            if (h != null)
                h(sender, e);
        };
    }
}

The WeakHandler base class

The WeakHandler is the based class for all delegate type. It provide automatic translation to a weak delegate build by the CreateHandler.

 
public abstract class WeakHandler<T> where T : class
{
    private T handler;
    private T implicitHandler;

    protected WeakHandler(T handler)
    {
        if (handler == null)
            throw new ArgumentNullException("handler");

        if (!(handler is Delegate))
        {
            throw new InvalidOperationException();
        }

        this.handler = handler;
    }

    protected abstract T CreateHandler(WeakReference weakReference);

    public static implicit operator T(WeakHandler<T> weakHandler)
    {
        if (weakHandler == null)
            return null;

        if (weakHandler.implicitHandler == null)
        {
            lock (weakHandler.handler)
            {
                if (weakHandler.implicitHandler == null)
                {
                    var ih = weakHandler.CreateHandler(new WeakReference(weakHandler.handler));
                    Thread.MemoryBarrier();
                    weakHandler.implicitHandler = ih;
                }
            }
        }

        return weakHandler.implicitHandler;
    }
}

 

How to use it

You can use the WeakEventHandler simply as if you where the EventHandler provided by the framework:


Form f = new Form();
f.SizeChanged += new WeakEventHandler(delegate(object sender, EventArgs e)
    {
        Console.WriteLine("Form changed.");
    });

 

Where are we?

We saw how to implement and reuse weak event handler. This event is very easy to create and reuse.

Happy Programming!

Testability of your Linq For Sql Model

I have already spoke with my friends about this. I think it’s the time to post it in my blog. Here is how I shield my implementation from the model.

Use an interface, not the class

Instead of using directly the DataModel generated by the Linq For Sql designer, you could use an interface representing your model.

public interface IDataContext
{
void SaveChanges();
}

public interface IEmployeeModel : IDataContext
{
void AddEmployee(Employee employee);
void DeleteEmployee(Employee employee);
IQueryable<Employee> Employees { get; }
}

We can see here that we have an interface that represent our model.

Customizing the generated partial class

The model generated by the Linq For Sql Designer is using a partial class. Using this feature, we can support for our IEmployeeModel interface. Here is how we do this:

partial class DataClasses1DataContext : IEmployeeModel
{
#region IEmployeeModel Members

public void AddEmployee(Employee employee)
{
if (employee == null)
throw new ArgumentNullException("employee");

this.Employees.InsertOnSubmit(employee);
}

void IEmployeeModel.DeleteEmployee(Employee employee)
{
if (employee == null)
throw new ArgumentNullException("employee");

this.Employees.DeleteOnSubmit(employee);
}

IQueryable<Employee> IEmployeeModel.Employees
{
get { return this.Employees; }
}

#endregion

#region
IDataContext Members

public void SaveChanges()
{
this.SubmitChanges();
}

#endregion
}

Implement a MockEmployeeModel class

After doing our real model, we can create a mock of our model to simulate database for very specific cases without touching the database. This way, we will be able to test even our Linq queries.



public class MockEmployeeModel : IEmployeeModel
{
private List<Employee> employees;

public MockEmployeeModel()
{
this.employees = new List<Employee>();
}

#region IEmployeeModel Members

public void AddEmployee(Employee employee)
{
if (employee == null)
throw new ArgumentNullException("employee");

this.employees.Add(employee);
}

public void DeleteEmployee(Employee employee)
{
if (employee == null)
throw new ArgumentNullException("employee");

this.employees.Remove(employee);
}

public IQueryable<Employee> Employees
{
get { return this.employees.AsQueryable(); }
}

#endregion

#region
IDataContext Members

public void SaveChanges()
{
// Nothing special to do here.
}

#endregion
}

Limitations


  • Compiled Linq queries are not supported. I will probably show you in a next post how to support it.


  • The MockModel is very limited. We would probably benefit having a mocking framework here.

Conclusion

As a typical use, we can now use normal linq queries over our model and test our queries in the very same manner using our MockEmployeeModel. This approach works with ADO.Net Entity Framework as well.



Happy Programming!

WPF: ComboBox and Null Values

When binding a ComboBox in WPF, you don’t have access to select a null value. There is several ways to allow ComboBox to select a null value:

  1. By Code: You can create a list of items and add a null item (not a null value but and item instance representing the null value). This is not reusable.
  2. By using a Converter: This is a bit more reusable but is not the best for scenario that already needs a converter. Also, this method require a convert from and a convert back of the value.
  3. By using an Attached Property: To me, this seems the ideal way (unless it is implemented directly by the ComboBox) to manage null value and this will be the technique describe here.

Here is how to create the Attached property:

public static class ComboUtil
{
private static readonly CommandBinding DeleteCommandBinding = new CommandBinding(ApplicationCommands.Delete, HandleExecuteDeleteCommand);

private static void HandleExecuteDeleteCommand(object sender, ExecutedRoutedEventArgs e)
{
var combo = e.Source as ComboBox;
if (combo != null)
combo.SelectedIndex = -1;
}

#region AllowNull Property

public static bool GetAllowNull(ComboBox combo)
{
if (combo == null)
throw new ArgumentNullException("combo");

return (bool)combo.GetValue(AllowNullProperty);
}

public static void SetAllowNull(ComboBox combo, bool value)
{
if (combo == null)
throw new ArgumentNullException("combo");

combo.SetValue(AllowNullProperty, value);
}

public static readonly DependencyProperty AllowNullProperty =
DependencyProperty.RegisterAttached(
"AllowNull",
typeof(bool),
typeof(ComboUtil),
new UIPropertyMetadata(HandleAllowNullPropertyChanged));

private static void HandleAllowNullPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var combo = (ComboBox)o;
if (true.Equals(e.NewValue))
{
if (!combo.CommandBindings.Contains(DeleteCommandBinding))
combo.CommandBindings.Add(DeleteCommandBinding);
}
else
{
combo.CommandBindings.Remove(DeleteCommandBinding);
}
}

#endregion
}



By using the above code, you will now be able to create a nullable comboBox by xaml only:



<ComboBox local:ComboUtil.AllowNull="true">
<
ComboBoxItem>Hello</ComboBoxItem>
<
ComboBoxItem>Hi</ComboBoxItem>
</
ComboBox>





and reset the combo by hitting the <DELETE> key when the ComboBox has the input focus.



Happy WPF programming!



Dany