Selecting Alternative Content When Silverlight Is Not Pre-Installed

Sometimes it may be desirable to select alternative HTML content if Silverlight is not installed. The functions in the standard Silverlight.js file provide everything we need.

Create a file called SilverlightSelector.js and paste in the following code.

if (!window.SilverlightSelector) window.SilverlightSelector = {
};
SilverlightSelector.selectContent = function(versions, installed, notInstalled) {
   var v = versions.split(";");
   var r = false;
   for (i = 0; i < v.length; i++) {
      r = Silverlight.isInstalled(v[i]);
      if (r == true) {
         break;
      }
   }
   if (r == true) {
      SilverlightSelector.setVisible(installed, true);
      SilverlightSelector.setVisible(notInstalled, false);
   }
   else {
      SilverlightSelector.setVisible(installed, false);
      SilverlightSelector.setVisible(notInstalled, true);
   }
}
 
SilverlightSelector.setVisible = function(id, value) {
   if (document.getElementById) {
      obj = document.getElementById(id);
      if (value == true) {
         obj.style.display == "";
      }
      else {
         obj.style.display = "none";
      }
   }
} 

The selectContent function accepts 3 parameters.

  1. versions, a ‘;’ delimited string containing the minimum supported versions.
  2. installed, the id of the html element to display if SIlverlight is installed.
  3. notInstalled, the id of the html element to show if Silverlight is not installed.

To use the script you need to include it in your page

<script type="text/javascript" src="SilverlightSelector.js"></script>

And then call it with appropriate parameters.

<div id="silverlightControlHost">
   <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
     <param name="source" value="ClientBin/MaxConnections.xap"/>
     <param name="onError" value="onSilverlightError" />
     <param name="background" value="white" />
     <param name="minRuntimeVersion" value="3.0.40818.0" />
     <param name="autoUpgrade" value="true" />
     <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none">
          <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
     </a>
   </object>
   <iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px">
   </iframe>
 </div>
<div id="noSilverlight">No Content</div>
<script type="text/javascript">
   SilverlightSelector.selectContent("3.0.40818.0", "silverlightControlHost", "noSilverlight");
</script>
One Comment Filed Under [ Silverlight ]
Silverlight, WCF, and ASP.Net Configuration Gotchas

I recently got involved in tracking down the answer to an interesting issue posted on the Silverlight forums. The problem was that all WCF calls were being executed sequentially, or in other words, only one WCF call was running at a time. This was having a drastic effect on performance.

Maximum Connections?

I knew there were some limitations on the number of concurrent WCF calls that could be made. If you are using the Browser HTTP stack, your are limited by the maximum number of concurrent connections the browser is configured to make against any one server. For IE this is configured in the registry and for Firefox it is configured by typing “about:config” in the address bar and then setting the “network.http.max-connections-per-server” option.

We checked these settings and found that the browser was configured for 15 concurrent connections.

The Test Application

At this point I decided to try and replicate the issue. To do this I created a new Silverlight application and added a very simple Silverlight-enabled WCF Service.

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TestService
{
   [OperationContract]
   public void LongCall()
   {
      Thread.Sleep(30000);
      return;
   }
 
   [OperationContract]
   public void ShortCall()
   {
      Thread.Sleep(3000);
      return;
   }
}

The idea was that I would first make a call to LongCall, and then follow it shortly after with a call to ShortCall and then wait to see which one finished first. If the calls were being dispatched in parallel I would normally expect ShortCall to finish first. I quickly added the service to the client using the Add Service Reference wizard and added the following snippet of test code.

var ref1 = new TestServiceClient();
ref1.LongCallCompleted += (s ,e) => Debug.WriteLine("Long:" + DateTime.Now);
ref1.LongCallAsync();
ThreadPool.QueueUserWorkItem((o) =>
   {
      Thread.Sleep(5000);
      ref1.ShortCallCompleted += (s, e) => Debug.WriteLine("Short:" + DateTime.Now);
      ref1.ShortCallAsync();
   });

I ran the code and…, good news (sort of), the short call finished well before the long call. Clearly Silverlight could make concurrent calls. So what was the problem?

Client Http Stack?

I knew the Client Http Stack (detailed here) bypassed the browser, so perhaps we could eliminate the browser as the culprit if I got the original poster to change his client to use it.

bool httpResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
bool httpsResult = WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);

After configuring the Client Http Stack the original poster found that his requests were now being processed concurrently! We still hadn’t isolated why the browser was only working sequentially, but we felt like we’d made progress.

Using Cookies with the Client Http Stack

Once we had changed the http stack a new problem arose, the http session was no longer begin maintained. This is because when you use the Client Http Stack its up to you to perform all cookie management. Fortunately this is relatively straight forward to fix, firstly you need configure your proxy classes to share a cookie container.

var ref1 = new TestServiceClient();
ref1.CookieContainer = SharedCookieContainer;

And then update your “.ClientConfig“ to enabled cookie containers for the binding.

<configuration>
    <system.serviceModel>
        <bindings>
           <basicHttpBinding>
              <binding name="BasicHttpBinding_TestService" maxBufferSize="2147483647"
                  enableHttpCookieContainer="true" maxReceivedMessageSize="2147483647">
                 <security mode="None" />
              </binding>
           </basicHttpBinding>

There is a good article here that covers this topic in more depth.

Things were looking good, we still didn’t know why the browser had been only allowing one request at a time, but we had a work around.

Browser Stack and Global.asax :(

Then we spotted a line in a post stating: “When using the browser HTTP stack, WCF sends requests sequentially on the same thread.”

Well, we knew this wasn’t true, because my really robust :) test application had proven it! But this no longer seemed to be an isolated issue, other people had seen it, and written about it, so what was going on?

After a bit of searching we finally found the answer. It turns out that if you have ASP.Net Session State enabled then all WCF calls made through the browsers http stack are executed sequentially. To enabled ASP.Net Session State you need to add a global.asax file to your server project that contains a session_start method. After I did this to my test project I was finally able to replicate the behaviour, problem solved!!!

Conclusion

We uncovered some pretty interesting behaviour during our problem solving session, hopefully that information is now all published in one place. Enjoy!

6 Comments Filed Under [ Silverlight WCF ]
MVVM – The Model - Part 1 – INotifyPropertyChanged

 

In this series I will be exploring the implementation of a simple base class for View Models. I will be primarily be focusing on Silverlight 3/4, however, most of the techniques should transfer to WPF with little or no change. I will cover topics such as:

  • Data Binding
  • Validation
  • Property Coercion and Formatting
  • Testing

 

Data Binding


Data Binding is a core component of the MVVM pattern, for an introduction to Data Binding check out this article from Microsoft. At the core of Data Binding is the INotifyPropertyChanged interface. This deceptively simple interface is used to synchronize property changes in a bound object with the UI layer.

public interface INotifyPropertyChanged
{
    event PropertyChangedEventHandler PropertyChanged;
}
 
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
 
 
 
 
 
 
 

The interface exposes a single event PropertyChanged. In addition to specifying that an individual property has changed the event can also indicate all properties of the object have changed by using either a null reference or String.Empty as the property name in the PropertyChangedEventArgs. Below is a typical implementation of the INotifyPropertyChanged interface:

public class Address : INotifyPropertyChanged
{
   private string _road;
 
   public string Road
   {
      get
      {
         return _road;
      }
      set
      {
         if (_road != value)
         {
            _road = value;
            RaisePropertyChanged("Road");
         }
      }
   }
 
   private void RaisePropertyChanged(string propertyName)
   {
      if (PropertyChanged != null)
         PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
   }
 
   #region INotifyPropertyChanged Members
 
   public event PropertyChangedEventHandler PropertyChanged;
 
   #endregion
}

As you develop more and more classes that implement the INotifyPropertyChanged event you will quickly come across two common and quite frustrating issues:

1). The code required to check for changes and raise the PropertyChanged event for each property is incredibly repetitive and tedious.

2). Its very easy to make a mistake and provide the wrong property name for the PropertyChangedEventArgs, either through failing to update code during refactoring or mistyping.

Simplifying the Property Setter Code

All of our property setter implementations follow the same basic pattern; compare the new value with the current value, and if the values differ assign the new value to the property’s backing field and raise the appropriate PropertyChanged event. We can write a generic method to achieve all of these steps as follows:

protected bool SetProperty<T>(ref T backingField, T value, string propertyName)
{
   var changed = !EqualityComparer<T>.Default.Equals(backingField, value);
   if (changed)
   {
      backingField = value;
      RaisePropertyChanged(propertyName);
   }
   return changed;
}

The use of “ref” parameters can often point toward a poor design, however, in this case its hard to argue with the elegance of the resulting property setter code:

public string Road
{
   get
   {
      return _road;
   }
   set
   {
      SetProperty(ref _road, value, "Road");
   }
}

The SetProperty method returns a boolean indicating whether the property was changed which can be used to by the property setter code to implement additional post processing, for example:

if (SetProperty(ref _road, value, "Road"))
    IsDirty = true;

In addition to this, by centralizing the property setter code we now have a single place to add additional features such as validation (which will be covered in the next article in the series).

Finally, for those of you using JetBrains Resharper (and seriously if you’re not why not), it is very easy to add a live template for properties.

<TemplatesExport family="Live Templates">
  <Template uid="bdff1468-958d-466a-9269-d84c92b1f055" shortcut="mprop" description="Model Property" text="public $Type$ $Name$&#xD;&#xA;{&#xD;&#xA;   get&#xD;&#xA;   {&#xD;&#xA;        return _$BackingField$;&#xD;&#xA;   }&#xD;&#xA;   set&#xD;&#xA;   {&#xD;&#xA;      SetProperty(ref _$BackingField$, value, () =&gt; $Name$);&#xD;&#xA;   }&#xD;&#xA;}&#xD;&#xA;&#xD;&#xA;private $Type$ _$BackingField$;$END$" reformat="True" shortenQualifiedReferences="True">
    <Categories />
    <Variables>
      <Variable name="Type" expression="guessExpectedType()" initialRange="0" />
      <Variable name="Name" expression="" initialRange="0" />
      <Variable name="BackingField" expression="decapitalize(Name)" initialRange="0" />
    </Variables>
    <CustomProperties />
  </Template>
</TemplatesExport>

Verifying the Property Name

I’m going to present two methods for verifying the property name.

Method 1 - Reflection

The first method is simple but effective, using reflection to verify that the property exists. Because reflection is quite costly the check is only performed if the code is compiled with the DEBUG conditional define. More sophisticated implementations could cache the property information for better performance.

protected void RaisePropertyChanged(string propertyName)
{
   VerifyPropertyName(propertyName);
   if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
 
[Conditional("DEBUG"), DebuggerStepThrough]
private void VerifyPropertyName(string propertyName)
{
   if (GetType().IsVisible)
   {
      if (!string.IsNullOrEmpty(propertyName) && GetType().GetProperty(propertyName) == null)
         throw new ArgumentException("Property name does not exists on target object.", "propertyName");
   }
}

The main problem with this mechanism is that the check is performed entirely at runtime.

Method 2 – LINQ Expression

The second method uses a LINQ Expression to determine the property name. This approach has the advantages of offering some degree of compile time checking, as well as better support for refactoring tools. There is a small overhead as the expression tree has to be created for each property set, however, in most cases this should be negligible.

protected bool SetField<T>(ref T field, T value, Expression<Func<T>> propertyExpression)
{
   var changed = !EqualityComparer<T>.Default.Equals(field, value);
   if (changed)
   {
      field = value;
      RaisePropertyChanged(ExtractPropertyName(propertyExpression));
   }
   return changed;
}
 
private static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
{
   var memberExpression = propertyExpression.Body as MemberExpression;
   if (memberExpression == null)
      throw new ArgumentException("Expression must be a MemberExpression.", "propertyExpression");
   return memberExpression.Member.Name;
}

To use this new mechanism we need to update our property set code as follows:

SetField(ref _road, value, () => Road);

Conclusion

The techniques presented here should help you create base classes for your Model classes that will reduce a lot of the mundane code usually required whilst adding some degree of verification. In my next article I will cover techniques for adding validation. The full source code for this article can be found here.

One Comment Filed Under [ Silverlight MVVM ]
Ensuring Consistency when Testing for ArgumentException Types

When writing tests that verify exceptions you need ensure that the method you are testing is in fact the method that raised the exception and that the details of the exception are as expected. To that end, many unit testing frameworks now include extensions such as “Assert.Throws<T>(Action a, string expectedMessage) where T : Exception”.

With many exception types the only additional detail you may be interested in is the Message, however, with ArgumentException types there are additional properties that should be checked for consistency such as ArgumentException.ParamName, or ArgumentOutOfRangeException.ActualValue.

   1: public void MethodUnderTest(string arg1)
   2: {
   3:     if (arg1 == null)
   4:         throw new ArgumentNullException("arg1");
   5:     // ...
   6: }
   7:  
   8: [TestMethod]
   9: public void If_Arguments_Are_Invalid_Should_Throw_Appropriate_Argument_Exception()
  10: {
  11:     var exception = AssertException.Throws<ArgumentNullException>(() => MethodUnderTest(null));
  12:     Assert.Equals("arg1", exception.ParamName);
  13: }

The problem with these types of test is that they can often be difficult to maintain, for example, if after a code review we decide “name” would be a better parameter name than “arg1” we may update are MethodUnderTest as follows:

   1: public void MethodUnderTest(string name)
   2: {
   3:     if (name == null)
   4:         throw new ArgumentNullException("arg1");
   5:     // ...
   6: }

Unfortunately we forgot to update the paramName string argument in the ArgumentNullException constructor. That's OK, our tests should pick that up…, except they don’t because we also forgot to update the argument name in our test! Even if we had remembered to update the paramName string  argument we would have still had to remember to locate and update our tests, which can be tedious for such trivial changes.

Although static code analysis, or tools such as Jet Brains Resharper will often pick up issues with argument exceptions they are not fool proof. Especially if you wrap these types of argument checks in a static utility class, for example Guard.ArgumentNull(“arg1”, arg1).

What we need is a way to ensure that the ParamName property in our exception is always consistent with the actual parameter defined in the code. We could use reflection to find out what the parameter name was, however, this would bloat our code quite significantly, an alternative is utilise the power of LINQ Expression Trees.

To distinguish between the standard Assert.Throws methods and our new Expression based approach we will create a new wrapper class for testing methods:

   1: public class MethodTest
   2: {
   3:    private readonly Action _execute;
   4:    private readonly MethodBase _method;
   5:    
   6:    public MethodTest(Expression<Action> expression)
   7:    {
   8:       var methodCallExpression = expression.Body as MethodCallExpression;
   9:       if (methodCallExpression == null)
  10:       {
  11:          var newExpression = expression.Body as NewExpression;
  12:          if (newExpression == null)
  13:             throw new ArgumentException("Expression body must be of type MethodCallExpression or NewExpression");
  14:          _method = newExpression.Constructor;
  15:       }
  16:       else
  17:       {
  18:          _method = methodCallExpression.Method;   
  19:       }
  20:       _execute = expression.Compile();
  21:    }
  22:  
  23:    private string GetParameterName(int index)
  24:    {
  25:       var parameters = _method.GetParameters();
  26:       if (parameters == null || index < 0 || index >= parameters.Length)
  27:          throw new ArgumentOutOfRangeException("index", index, "Index out of range.");
  28:       return parameters[index].Name;
  29:    }
  30:  
  31:    public T AssertThrows<T>() where T : Exception
  32:    {
  33:       return AssertException.Throws<T>(Execute);
  34:    }
  35:  
  36:    public T AssertThrowsArgumentException<T>(string message, int parameterIndex) where T : ArgumentException
  37:    {
  38:       var exception = AssertThrowsArgumentException<T>(parameterIndex);
  39:       Assert.AreEqual(message, exception.Message);
  40:       return exception;
  41:    }
  42:  
  43:    public T AssertThrowsArgumentException<T>(int parameterIndex) where T : ArgumentException
  44:    {
  45:       var exception = AssertException.Throws<T>(Execute);
  46:       Assert.AreEqual(GetParameterName(parameterIndex), exception.ParamName);
  47:       return exception;
  48:    }
  49:  
  50:    public ArgumentException AssertThrowsArgumentException(string message, int parameterIndex)
  51:    {
  52:       return AssertThrowsArgumentException<ArgumentException>(message, parameterIndex);
  53:    }
  54:  
  55:    public ArgumentException AssertThrowsArgumentException(int parameterIndex)
  56:    {
  57:       return AssertThrowsArgumentException<ArgumentException>(parameterIndex);
  58:    }
  59:  
  60:    public ArgumentNullException AssertThrowsArgumentNullException(string message, int parameterIndex)
  61:    {
  62:       return AssertThrowsArgumentException<ArgumentNullException>(message, parameterIndex);
  63:    }
  64:  
  65:    public ArgumentNullException AssertThrowsArgumentNullException(int parameterIndex)
  66:    {
  67:       return AssertThrowsArgumentException<ArgumentNullException>(parameterIndex);
  68:    }
  69:  
  70:    public ArgumentOutOfRangeException AssertThrowsArgumentOutOrRangeException(string message, object actualValue, int parameterIndex)
  71:    {
  72:       var exception = AssertThrowsArgumentOutOrRangeException(actualValue, parameterIndex);
  73:       Assert.AreEqual(message, exception.Message);
  74:       return exception;
  75:    }
  76:  
  77:    public ArgumentOutOfRangeException AssertThrowsArgumentOutOrRangeException(object actualValue, int parameterIndex)
  78:    {
  79:       var exception = AssertThrowsArgumentException<ArgumentOutOfRangeException>(parameterIndex);
  80:       Assert.AreEqual(actualValue, exception.ActualValue);
  81:       return exception;
  82:    }
  83:  
  84:    private void Execute()
  85:    {
  86:       _execute();
  87:    }
  88: }

This class takes a LINQ Expression, verifies that it represents a call to a Method or a Constructor and extracts the underlying MethodBase which can be used to verify argument names. We can now alter our tests to use this new class as follows:

   1: [TestMethod]
   2: public void If_Arguments_Are_Invalid_Should_Throw_Appropriate_Argument_Exception()
   3: {
   4:     new MethodTest(() => MethodUnderTest(null))
   5:         .AssertThrowsArgumentNullException(0);
   6: }

This test will now verify that an ArgumentNullException is thrown with the ParamName property equal to the parameter name at position zero.

Add Comment Filed Under [ Testing ]
Microsoft Chess – Tuning Test Performance

Following on from my previous blog First Encounters with Microsoft Chess

My next test involved adding multiple continuations, all from different threads. The aim of this test was to verify that the code for adding and dispatching continuations was thread safe. Below is the initial version of that test.

   1: [TestMethod]
   2: [HostType("CHESS")]
   3: public void If_Adding_Multiple_Continuations_On_Different_Threads_Should_Run_All_Continuations()
   4: {
   5:     var task = Task.Factory.From(() => MockActions.DoNothing);
   6:          
   7:     var done = new int[1];
   8:          
   9:     ThreadPool.QueueUserWorkItem(
  10:         s => task.ContinueWith(() => Interlocked.Increment(ref done[0]), Task.Factory));
  11:     ThreadPool.QueueUserWorkItem(
  12:         s => task.ContinueWith(() => Interlocked.Increment(ref done[0]), Task.Factory));
  13:     ThreadPool.QueueUserWorkItem(
  14:         s => task.Start());
  15:          
  16:     Assert.IsTrue(AsyncRunner.SleepUntil(() => done[0] == 2, 2000));
  17: }

When I ran this test it took 1.5 hours to run with over 118,000 schedules!! Although it passed :), this was clearly not a good place to be, CI would be a nightmare.

I was reluctant to change the code in my tasks so I started to look at the test itself, could I reduce the number of schedules just by changing my test. I realized I might not need to change much as the number of schedules explored grew exponentially.

The first thing I did was to go back to only adding one continuation, clearly waiting 1.5 hours for each change I made wouldn’t allow me to make much progress. By removing the additional continuation the test reduced to 2875 schedules and took 2 minutes to run, much better, something I can work with.

Once I had done this, I replaced the Interlocked.Increment calls. As these calls are part of the Threading API, CHESS explores their interleaving. This reduced the test to 2684 schedules and took about 1 minute 40 seconds.

Next I set my continuations to use the synchronous scheduler, after all I wasn’t really interested in how the continuation tasks ran, just that they did. This reduced the test to 1479 schedules and took about 30 seconds to run.

I then realized that I didn’t need to invoke task.Start on a separate thread, CHESS would still explore scenarios such as adding a continuation before calling start without the extra thread. I was now down to 582 schedules and about 15 seconds.

At this point I felt I had done pretty much all that I could so I re-added the second continuation. The final result, 9347 schedules taking about 3 minutes. Although still not ideal, I was pretty happy, after all this test covered a large number of scenarios, and was a hell of a lot more thorough than I could have done by hand.

The final code is below:

   1: [TestMethod]
   2: [HostType("CHESS")]
   3: public void If_Starting_And_Adding_Continuations_On_Different_Threads_Should_Execute_All_Continuations()
   4: {
   5:     // create task
   6:     var task = Task.Factory.From(() => MockActions.DoNothing);
   7:  
   8:     var done1 = false;
   9:     var done2 = false;
  10:  
  11:     ThreadPool.QueueUserWorkItem(
  12:         s => task.ContinueWith(() => done1 = true, TestFactories.Synchronous));
  13:     ThreadPool.QueueUserWorkItem(
  14:         s => task.ContinueWith(() => done2 = true, TestFactories.Synchronous));
  15:  
  16:     task.Start();
  17:  
  18:     Assert.IsTrue(AsyncRunner.SleepUntil(() => done1 && done2, 2000));
  19: }
Add Comment Filed Under [ Testing Asynchronous ]
Adding Multi-Tenant Support to an Existing Application

Over the past few weeks I’ve been working on adding Multi-Tenancy support to iMeta Agility. This has enabled us to release a free community version with all the advantages of a SaaS/Cloud deployment model.

What is Multi-Tenancy

For those of you not familiar with Multi-Tenancy, Microsoft has a good primer here.

General Approach

After some investigation, and prototyping we decided to go with a Shared Database\Shared Schema approach.  With this approach tables include records from multiple tenants; utilising a Tenant ID column to associate each record with the appropriate tenant.

Aa479086.mlttntda05(en-us,MSDN.10).gif

The strategy for securing data access (as described in the Microsoft article above) involves creating a SQL Server user account for each tenant, and restricting access to the data through views pivoted on the current account.

   1: CREATE VIEW TenantMyTable AS 
   2: SELECT * FROM MyTable WHERE TenantID = 
   3: SUSER_SID()

There are however a couple of issues with this approach:

  • The view (as declared above) does not prevent users from inserting or updating data in another tenancy.
  • A connection pool is created for each tenant, leading to less effective connection pooling.
  • If porting an existing application we need to update all of the data access logic to work with the new views.

 

Preventing Inserts,Updates and Deletes on the View

Fortunately, restricting inserts, updates and deletes on the view is relatively easy. By adding the “WITH CHECK OPTION” to our view we can ensure that any attempt to create/modify records that do not match the “TenantID = SUSER_SID()” will fail.

   1: CREATE VIEW TenantMyTableView AS 
   2: SELECT * FROM MyTable WHERE TenantID 
   3: = SUSER_SID() 
   4: WITH CHECK OPTION

Any attempt to create/modify a record where TenantID is not equal to SUSER_SID() will result in the following error:

“Msg 550, Level 16 The attempted insert or update failed because the target view either specifies WITH CHECK OPTION or spans a view that specifies WITH CHECK OPTION and one or more rows resulting from the operation did not qualify under the CHECK OPTION constraint.”

Sharing the Connection Pool Across Tenants

To prevent each tenancy from requiring its own connection pool we need to share a single connection string across multiple tenants. This means we cannot associate a user account with each tenant, which in turns means we cannot filter our view using the SUSER_SID() function. We need an alternative mechanism for associating a tenant with a session.

At this point some of you may be thinking temporary tables, however, temporary tables are not accessible within views. In fact, our options are pretty limited as SQL server does not really support the concept of general user defined session variables. The only option (we’ve found) is to use the CONTEXT_INFO variable and the corresponding CONTEXT_INFO() function. CONTEXT_INFO and CONTEXT_INFO() enables applications to set binary values of up to 128 bytes that can be referenced in multiple batches, stored procedures, triggers, or user-defined functions operating on the same session. More information working with session context information can be found here.

To allow the information stored in CONTEXT_INFO to be access in a strong typed manner we simply wrap read/write with a stored procedure and function.

   1: CREATE FUNCTION [dbo].GetCurrentTenantID()
   2: RETURNS int
   3: AS
   4: BEGIN
   5:     RETURN CAST(CAST(CONTEXT_INFO() AS BINARY(4)) AS INT)
   6: END
   7: GO
   8:  
   9: CREATE procedure [dbo].SetCurrentTenantID(@p_Value int)
  10: AS
  11: BEGIN
  12:   SET CONTEXT_INFO @p_Value
  13: END
  14: GO

And then update our view to pivot off of the function.

   1: CREATE VIEW TenantMyTableView AS 
   2: SELECT 
   3:     * 
   4: FROM 
   5:     MyTable 
   6: WHERE 
   7:     TenantId = [dbo].GetCurrentTenantID()

Now, in our data access logic, all we need to do is ensure that SetCurrentTenantID is set whenever a connection is required. We do not need to worry about clearing the value of CONTEXT_INFO as all variables are automatically reset by the connection pool when connections are released.

   1: var connection = new SqlConnection(_connectionString);
   2: try
   3: {
   4:     connection.Open();
   5:     try
   6:     {
   7:         var identity = AgilitySecurity.GetCurrentIdentity(false);
   8:         if (identity != null)
   9:         {
  10:             var command = connection.CreateCommand();
  11:             command.CommandType = CommandType.StoredProcedure;
  12:             command.CommandText = "dbo.SetCurrentTenantID";
  13:             command.Parameters.Add(new SqlParameter("@p_Value", identity.TenantId));
  14:             command.ExecuteNonQuery();
  15:         }
  16:     }
  17:     catch
  18:     {
  19:         connection.Close();
  20:         throw;
  21:     }
  22: }
  23: catch (Exception e)
  24: {
  25:     ServerTrace.TraceException(TraceCategory.DataAccess, 
  26:         "Failed to open connection.", e);
  27:     throw DataAccessExceptions.ConnectionOpenError(e);
  28: }
  29: return connection;

 

Getting the Application Working With the Tenanted Views.

Once we are finished with the previous steps we need to get our application to work with the tenanted views. Updating all of the data access logic, even if using something like NHibernate or LINQ can be quite tedious, it would be better if we didn’t have to make any of those changes. It would be even better if the application could be large unchanged, and not even have to worry about the fact it is now tenanted.

To achieve this we need to create a new schema and make it the default schema for our connection. In our example, we will call the new schema “Tenancy”. We can then define views in the Tenancy schema that look identical to our original tables.

   1: CREATE VIEW Tenancy.MyTable AS 
   2: SELECT 
   3:     Field1,
   4:     Field2
   5: FROM 
   6:     [dbo].TenantMyTableView

We now have a schema that looks like our original schema, but with tenancy built in. There is only one issue left to solve; we need to tell the SqlServer how to insert the TenantID automatically when a new record is inserted. To do this we simply add a default constraint on MyTable.

   1: ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DefaultTenancyId]  DEFAULT ([dbo].[GetCurrentTenantID]()) FOR [TenantID]
   2: GO

Conclusion

As you can see there is a common set of steps that need to be applied to each table that needs to be tenanted. This makes it relatively easy to tenant a non-tenanted application with minimal code changes. Existing stored procedures, functions etc. can be moved to the Tenancy schema without change. I look forward to someone writing a tool to automate this :)

One Comment Filed Under [ Cloud SaaS ]
First Encounters with Microsoft Chess

Recently I've been working on an open source asynchronous framework for Silverlight based on the task library shipped in .NET 4. One of the main challenges of writing any asynchronous code is testing. Anyone that has experience with testing asynchronous code will know that even if you run your tests thousands of times, and they pass, it doesn’t mean the code is correct . The problem is that you cannot easily control when threads will be scheduled, which means its very difficult to determine if all the possible interleaving scenarios have been tested.

Then I discovered Microsoft CHESS, “CHESS repeatedly runs a concurrent test ensuring that every run takes a different interleaving. If an interleaving results in an error, CHESS can reproduce the interleaving for improved debugging.”

I’m not going to go into detail on how to use CHESS, plenty of information can be found on the web site. As a good starting point I’d recommend watching this video http://channel9.msdn.com/posts/Peli/Getting-started-with-CHESS-in-Visual-Studio-2008. What I am going to do is document my experiences, including any gotchas I’ve encountered, hopefully as a series, if time permits.

My first test

The first test I wrote using CHESS related to continuations, I needed to ensure that continuations for a task were always run when a task was completed. Continuations can be added at any time, and from any thread. This means they can be added before or after the task has started, and before or after it has completed.

   1: [TestMethod]
   2: [HostType("CHESS")]
   3: public void If_Adding_Continuation_On_Different_Thread_Should_Run_Continuation()
   4: {
   5:     var completedEvent = new ManualResetEvent(false);
   6:          
   7:     var task = Task.Factory.From(() => MockActions.DoNothing);
   8:     ThreadPool.QueueUserWorkItem(
   9:         s => task.ContinueWith(() => completedEvent.Set(), TestFactories.Synchronous));
  10:     task.Start();
  11:         
  12:     Assert.IsTrue(completedEvent.WaitOne(2000));
  13: }

I wasn’t all together surprised when my test failed, it was perfectly possible I had missed something in my implementation. So I followed the instructions for reproducing the specific interleaving that had caused the test to fail, only to find that chess did not break the debugger on any of my code. I decided to increase the timeout on my WaitOne call to 10 seconds to see if running under chess was having an effect on my timings; the test failed immediately.

At this point I realized that CHESS was exploring all of the routes for all of my code, including the code in the test. CHESS was simulating a timeout on the WaitOne call, which meant my test would always fail. In a way this is cool, as it means your test code, is being tested to some degree. In future version of CHESS there will be additional features for excluding particular namespaces, assemblies, etc.

In the mean time, the solution was to write a safe wait utility method that could be used without effecting the interleaving.

   1: public static bool SleepUntil(Func<bool> condition, int timeout)
   2: {
   3:     var sw = new Stopwatch();
   4:     sw.Start();
   5:     while (!condition() && sw.ElapsedMilliseconds < timeout)
   6:         Thread.Sleep(0);
   7:     return condition();
   8: }
One Comment Filed Under [ Testing Asynchronous ]
Input Localization in Silverlight without IValueConverter

 

The Problem

There are plenty of articles on the web detailing how to localize strings within Silverlight applications, however, one area of confusion seems to be how to get Silverlight to accept text input using the users current culture settings.

For example, if I type 10,1 in a locale that uses the ‘,’ symbol as the decimal symbol I might expect to get the decimal number “10.1” (UK Format), however, I will in fact receive the number 101.

Many examples demonstrate using custom IValueConverter implementations that format and parse values using the current culture to work around this issue , however, this method is tedious, error prone, and unnecessary.

Solution

By default, bindings in Silverlight that do not specify a custom ValueConverter parse input text using the culture specified by the target elements Language property. The Language property is of type XmlLanguage and is one of the few built in inherited properties supported in Silverlight. This means that setting the Language property of the RootVisual will cause all text to be parsed using the users current culture.

One thing to keep in mind is that by default Popup (and descendents such as ChildWindow) do not belong to the root visual tree and will therefore need to be configured independently (or added to the visual tree).

Below is a simple class that returns an XmlLanguage object for the current culture

   1: public class CultureSettings
   2: {
   3:   public XmlLanguage Language
   4:   {
   5:      get
   6:      {
   7:         return XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name);
   8:      }
   9:   }
  10: }

The class is added to the Applications resources

   1: <Application.Resources>
   2:     <ResourceDictionary>
   3:         <Windows:CultureSettings x:Key="CultureSettings"/>
   4:     </ResourcesourceDictionary>
   5: </Application.Resources>
   6:  

And finally bound to the Language property of the root visual

   1: <ContentPresenter x:Name="RootVisual" Language="{Binding Language, Source={StaticResource CultureSettings}}"/>
2 Comments Filed Under [ Silverlight ]
iMeta Agility Beta is Live!!!

I’m pleased to announce that iMeta Agility Beta is now live!!! iMeta Agility is an entry level tool for managing Agile projects written in Silverlight. Check it out at http://www.imeta.co.uk/Consultancy/Agility.aspx 

All feedback welcome :)

Perhaps now I’ll have more time to Blog about our adventures in Silverlight

MSTest and Silverlight

One thing missing from the Microsoft Silverlight testing framework is Visual Studio integration. Because of this many people end up using the standard non-Silverlight MSTest framework to test their Silverlight code. At first this may sound a little balmy, however, Silverlight assemblies are byte code compatible with normal .NET assemblies and will quite happily run within CLR 2.0. There are a few things, however, you should be aware of:

  1. You can only make calls to APIs that do not require the underlying Silverlight core (agcore), so anything inheriting from DependencyObject is out, as is WCF.
  2. The [SecurityCritical] attribute is ignored, meaning that calls that would normally be prohibited within Silverlight can be made without resulting in a MethodAccessException.

The limitations described in point one may at first seem quite significant, however, if you are abstracting your UI logic using some flavour of MVVM, MVC, MVP, etc. you will more than likely find that your code does not fall into this category, and WCF calls in most cases should be mocked.

The advantage of running your tests within Visual Studio is that you do not need to run all of your tests for each test run, which is particularly useful if you are following a TDD approach. The downside of course is that you have to be confident that running your tests within this environment does not affect the outcome of your tests, its a trade off.

Creating the Test Project

In Visual Studio create a normal (non-Silverlight) test project.

image

(At iMeta we use the “Hybrid” prefix to indicate we are mixing Silverlight and .Net code).

Remove all references from the project except for the reference to Microsoft.VisualStudio.QualityTools.UnitTestFramework

image

Re-add any required references but this time selecting Silverlight assemblies, usually located within “C:\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v3.0” and “C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Libraries

5 Comments Filed Under [ Silverlight Testing ]