Sunday, March 23, 2014

Conditional Deployment of Resources in Xamarin Android


I was recently out at a client site and they asked me how to conditionally deploy resources in Xamarin Android.  They have a situation where they have one base application that they are creating and depending on the brand deploy a completely different set of resources.  It is important to note that they only want to deploy the resources that would be particular to that brand so as not to bloat the overall application with a bunch of images/strings that would never be used.  At the time this seemed like an interesting problem but one that I had never tried.  With a little digging I found an answer on the Xamarin site: 

Xamarin - Build Process

The Xamarin instructions are at a pretty high level and sometimes they need some experimentation to figure out all the wrinkles.  I decided to try this out and I wanted a solution that would meet the following criteria:

- It should allow for one set of resources to be shared for all brands and some resources to be brand specific
- It should be easy to specify building for one brand or the other
- It should support all types of resources, strings, views, images, etc
- It should be easy to setup and maintain

From the above article this will require some manual editing of the project file in something like notepad.  This means right off the bat my fourth requirement of "It should be easy to setup and maintain" is going to be a bit tenuous (note to self: perhaps a Visual Studio plugin could be made for this so it can be done through the UX?). 

First thing I did was set up a new project called MyResourceTest and renamed Activity1.cs to MainActivity.  That creates an Android project that looks like this:














I want to have a shared image and a shared string.  I use the default icon as my shared image and in the default strings.xml I change the string resources to contain a single value, SharedString:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="SharedString">Shared string used by all</string>
</resources>

Then I modify the Main.axml to display the shared string:
 


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  <TextView
      android:id="@+id/lblShared"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/SharedString" />
</LinearLayout>

Finally I remove the code for the button that was created by default in the MainActivity.cs:

using Android.App;
using Android.OS;

namespace MyResourceTest
{
    [Activity(Label = "", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);
        }
    }
}

When I run this I get a very unexciting application, nothing new here:


























This is where the fun starts.  I want to add an image and a couple of strings that vary as far as what gets deployed based on what configuration I choose.  My application brands are going to be named AppOne and AppTwo and so I need to create four new configurations Debug-AppOne, Debug-AppTwo, Release-AppOne and Release-AppTwo.  I copy the default Debug and Release configurations to my new configurations as appropriate.  When I’m done I remove the default Debug and Release configurations because I won’t need them anymore.  The complete configuration setup looks like this:





















Now I’ll set up the directory structure to support my new applications.  In the project I’m going to create two new directories from the root of the project, Resources-AppOne, Resources-AppTwo.  Under each of these projects will be a Drawable and Values folder:


























Note: That there are now three resources directories, one for  our shared resources, one for the brand resources specific to AppOne and one for resources specific to AppTwo.  I could just as easily add a Layout folder to each of the new resources folders to have brand specific views.

To the Resources-AppOne\Drawable folder I add an image for AppOne called MainLogo.png and add an AppTwo MainLogo.png picture to the Resources-AppTwo\Drawable folder.  These will be two different images with the same name.  Be careful, if you add an image to one brand specific folder you will have to have an equivalent version with the same name in the other brand specific folders or have code in your application to handle the case where it might be missing.

To each of the brand specific Values folder I add a new xml file for my strings called strings-app.xml.  This needs to have a different name than any of the files under the default Resources\Values folder or you will have a collision at compile time.  In each of the files I set up two string values, ApplicationName, AppDescription.
File for Resources-AppOne\Values\Strings-App.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="ApplicationName">First Application</string>
    <string name="AppDescription">The First Application</string>
</resources>

File for Resources-AppTwo\Values\ Strings-App.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="ApplicationName">Second Application</string>
  <string name="AppDescription">The Second Application</string>
</resources>


Note: I make sure the build action for all of these files is set to AndroidResource for them to be used as Android Resources by the compiler.

I want to use my new image and strings in my view, Main.xml.  I change it to be as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  <TextView
      android:id="@+id/lblShared"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/SharedString" />
  <TextView
      android:id="@+id/lblDescription"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/AppDescription" />
  <ImageView
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:id="@+id/imgMain"
      android:src="@drawable/MainLogo"
      android:scaleType="fitCenter"/>
</LinearLayout>

Finally I also want the application’s title to use my brand specific ApplicationName string resource.  To do this I override the MainActivity’s OnAttachedToWindow event to use the ApplicationName string resource:

public override void OnAttachedToWindow()
{
    base.OnAttachedToWindow();
    this.Window.SetTitle(GetString(Resource.String.ApplicationName));
}

If I decide to try and run this now I’m going to get a couple of errors, the compiler doesn’t know how to deal with the Resources-AppOne or Resources-AppTwo folders.  Errors similar to the following appear:










This is where it gets a little difficult.  We can’t do what we want in the IDE, instead we need to edit the project file directly in a tool like Notepad.  If I open the project in Notepad and view my newly added brand specific files this is what I find:









I want to pull out the AppOne and AppTwo resources into their own ItemGroups that are conditionally included in the project if one of the AppOne or AppTwo configurations we added before are selected.  When done your project file should look similar to this:

<ItemGroup Condition="'$(Configuration)'=='Debug-AppOne'Or'$(Configuration)'=='Release-AppOne'">
    <AndroidResource Include="Resources-AppOne\Drawable\MainLogo.png" />
    <AndroidResource Include="Resources-AppOne\Values\Strings-App.xml">
      <SubType>Designer</SubType>
    </AndroidResource>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug-AppTwo'Or'$(Configuration)'=='Release-AppTwo'">
    <AndroidResource Include="Resources-AppTwo\Drawable\MainLogo.png" />
    <AndroidResource Include="Resources-AppTwo\Values\Strings-App.xml">
      <SubType>AndroidResource</SubType>
    </AndroidResource>
</ItemGroup>
<ItemGroup>
    <Content Include="Properties\AndroidManifest.xml" />
</ItemGroup>

There is one more thing we need to do.  If you recall the compiler won’t see the Resources-AppOne or Resources-AppTwo directories as being valid.  We need to map them correctly in the project file.  Add two new conditional PropertyGroups, one for AppOne and one for AppTwo, to correctly map the directories:

<PropertyGroup Condition="'$(Configuration)'=='Debug-AppOne'Or'$(Configuration)'=='Release-AppOne'">
    <MonoAndroidResourcePrefix>Resources;Resources-AppOne</MonoAndroidResourcePrefix>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug-AppTwo'Or'$(Configuration)'=='Release-AppTwo'">
    <MonoAndroidResourcePrefix>Resources;Resources-AppTwo</MonoAndroidResourcePrefix>
</PropertyGroup>

If I save the project file and reopen it, the project will use the correct resources for the configuration I have selected.  If I select Debug-AppOne and run the application this is what I see:
























If I then select the Debug-AppTwo profile I see this:
























Remember, this is doing more than just using the correct resources at run time like when you have language specific resources, it is only compiling in the resources specified by the selected configuration.  To verify this you can examine the obj output folders for the appropriate configuration.  Compiling in an alternate set of resources is as simple as changing the selected configuration from Debug-AppOne to Debug-AppTwo.  In general this satisfies all my conditions other than it does take some time to setup and to maintain.  That is, if new drawable resources are added to the brand specific resource directories you will still need to modify the project file directly and make sure they show up under the correct conditional ItemGroups. 

There are probably other ways to do this such as using your source control solution with some sort of branching strategy but that seems too difficult to manage.  As I indicated earlier at some point a Visual Studio plugin could be added to make this easier to do through the UX but at the present time as indicated on the Xamarin site this would seem to be the easiest way to do it.

Tuesday, February 18, 2014

The High Cost of Cross Platform Standards

Recently Jason Bock posed a question to our company about where should validation happen in an application; on the client, on the server, both?  In the past the pendulum in the world of application development has swung back and forth between thin and thick client and as it has the location of validation has shifted.  Green screen terminals with heavy logic on the back end, one and two tier applications with the majority of validation in the client.  The rise of COM with the ability of creating n-tier applications where the same business logic could be written on the client and the server (I'll ignore the fact that so many people did this poorly).

How did this all happen?  Companies were able to unilaterally innovate and proprietary systems reigned supreme.  With the rise of the PC companies made DBase, FoxPro, VB; each was independently successful on the PC platform.  Several years later MS could unilaterally put COM in place and later .Net.  These were more than just languages, frameworks and syntactic sugar, they were designed to allow new paradigms.

Since the late '90s we are now also in the world of HTML and JavaScript.  These represented a cross platform standard which is great.  Theoretically we can write applications once and they will run anywhere.  Of course in practice this is more like write once and tweak everywhere but the promise is there.  When web applications first started being written they were amazingly primitive.  Mostly just simple validation with much of the complex validation and business logic happening on the server.  But, as has happened in the past the people using the applications wanted a richer experience.  Over time, in a glacially slow progression, we started getting tools to allow this such as AJAX, JQuery and eventually a whole plethora of new JavaScript frameworks like Knockout and Angular.

Now we have all kinds of cool things like TypeScript and SPA frameworks all is good in the world, right?  Maybe, but maybe not.  The agreement on and adoption of HTML5 has been glacially slow.  Without a change to JavaScript or the HTML standard any new innovations must be layered on top of what is already there.  It is very hard with something like HTML and JavaScript to do fundamental changes like creating COM or the .Net framework.  For example, Google has been working on native object binding in HTML with Object.Observe() but of course it's not that easy to get something like that in the standard.  What do they have to do instead?  Build binding in Angular which of course is written in JavaScript and much slower than native data binding would have been.  How long do we wait for new JavaScript extensions and HTML 6?

In answer to Jason's question: the users will continue to demand richer and richer applications.  This means that business logic will have to be written in the browser in JavaScript or something layered on top of JavaScript.  To make sure that the information being sent to the web server is correct we will end up writing it again in C#, emiting simple JavaScript based on logic written in C# or running to node.js to write our server side validation so we only write the business logic once in JS.  What is not easily possible is to quickly make a major change in the underlying technologies of HTML and JavaScript to make a better, easier language to meet these demands. 

For better or for worse we have the cross platform advantages that JavaScript represents while we work around the slow pace of change that the cross platform also represents.  The people we write applications for are not going to be willing to wait for the language to change on its own so there will continue to be a place for Node.js, Angular, JQuery, Knockout and TypeScript.  Constructs written on top of JavaScript will do their best to make up for what the language can't do or isn't optimized to do.  A cross platform language like JavaScript cannot directly keep up with the pace of change that our industry demands.

Tuesday, December 17, 2013

CSLA, Inversion of Control and Unit Testing: Part 1 Sending an interface to the CSLA Data Portal

This post is part one in a multi part series on Inversion of Control (IoC) and unit testing in the CSLA framework. 

As most of you know, IoC can reduce coupling within our applications.  CSLA has many new features that support this.  For the purposes of this blog post I'm using CSLA version 4.5.4.

How do we get started?  I'll start with creating the interfaces that we will use.  The five most common stereotypes in CSLA are BusinessBase, BusinessListBase, ReadOnlyBase, ReadOnlyListBase and CommandBase.  With each of these we can make an interface for our concrete classes that in turn inherits from the appropriate CSLA interfaces for these types:

A sample interface for BusinessBase:

   1:  public interface ITestBusinessBase : Csla.IBusinessBase
   2:  {
   3:      int Id { get; }
   4:      string Name { get; set; }
   5:      void SomeMethod(string someParameter);
   6:  }


A sample interface for BusinessListBase and a leaf:

   1:  public interface ITestBusinessBaseLeaf : Csla.IBusinessBase
   2:  {
   3:      int Id { get; }
   4:      string Name { get; set; }
   5:  }
   6:      
   7:  public interface ITestBusinessCollectionBase : Csla.IBusinessListBase<ITestBusinessBaseLeaf>
   8:  {
   9:  }

A sample interface for ReadOnlyBase:

   1:  public interface ITestReadOnlyBase : Csla.IReadOnlyBase
   2:  {
   3:      int Id { get; }
   4:      string Name { get; }
   5:  }

A sample interface for ReadOnlyListBase:

   1:  public interface ITestreadOnlyBaseLeaf : Csla.IReadOnlyBase
   2:  {
   3:      int Id { get; }
   4:      string Name { get; set; }
   5:  }
   6:   
   7:  public interface ITestReadOnlyListBase : Csla.IReadOnlyListBase<ITestreadOnlyBaseLeaf>
   8:  {
   9:  }

A sample interface for CommandBase:

   1:      public interface ITestCommandBase : Csla.ICommandBase
   2:      {
   3:          bool SomeResult();
   4:      }

One thing to notice here is there are no static methods and the CSLA samples generally use static factory methods.  Why is this?  Unfortunately static methods are not able to be added to an interface in C# so if we still use factory methods we need to be aware that any code that uses them may be tied to the concrete class that defines them.  This may, or may not, be OK depending on what we are trying to do.  It is important to note that the static factory method could still use an IoC container to resolve out the object factory and instance that it is creating.

Ok, so what's next?  I use an IoC container, for the purposes of this posting I'll use Autofac.  Generally in our production code we are going to use the same IoC container for all operations.  I use a Service Locator pattern for this.  There are some schools of thought that declare this pattern to be somehow wrong but I don't subscribe to that philosophy.  Generally if you use ASP MVC you are already using service locators to resolve out the routes and to bind your post backs to your models.  I'm not going to get too far into why the Service Locator pattern may in some cases be appropriate but suffice it to say if you are using CSLA, you will need to buy into the idea that Service Locators are at least not harmful. 

The following static class gives me program wide reference to my IoC container.  At some point I need to set the Container property for use:

   1:  public static class IoC
   2:  {
   3:      public static Autofac.IContainer Container { get; set; }
   4:  }

Another CSLA component that we may take a dependency on is the DataPortal itself.  I generally abstract this out behind my own implementation using CSLA's IDataPortal<T> interface.  For the purpose of this post, I created an IObjectFactory interface to also expose out the "child" DataPortal methods that are not part of the IDataPortal<T> interface:

   1:  public interface IObjectFactory<T> : IDataPortal<T>
   2:  {
   3:      TC CreateChild<TC>();
   4:      TC CreateChild<TC>(params object[] parameters);
   5:      TC FetchChild<TC>();
   6:      TC FetchChild<TC>(params object[] parameters);
   7:      void UpdateChild(object child);
   8:      void UpdateChild(object child, params object[] parameters);
   9:  }

The concrete implementation of the ObjectFactory class would be as so:

   1:  public sealed class ObjectFactory<T> : Common.Interfaces.IObjectFactory<T> where T : class, IMobileObject
   2:  {
   3:      public void BeginCreate(object criteria, object userState)
   4:      {
   5:          DataPortal.BeginCreate(criteria, CreateCompleted, userState);
   6:      }
   7:   
   8:      public void BeginCreate(object criteria)
   9:      {
  10:          DataPortal.BeginCreate(criteria, CreateCompleted);
  11:      }
  12:   
  13:      public void BeginCreate()
  14:      {
  15:          DataPortal.BeginCreate(CreateCompleted);
  16:      }
  17:   
  18:      public void BeginDelete(object criteria, object userState)
  19:      {
  20:          DataPortal.BeginDelete(criteria, DeleteCompleted, userState);
  21:      }
  22:   
  23:      public void BeginDelete(object criteria)
  24:      {
  25:          DataPortal.BeginDelete(criteria, DeleteCompleted);
  26:      }
  27:   
  28:      public void BeginExecute(T command, object userState)
  29:      {
  30:          DataPortal.BeginExecute(command, ExecuteCompleted, userState);
  31:      }
  32:   
  33:      public void BeginExecute(T command)
  34:      {
  35:          DataPortal.BeginExecute(command, ExecuteCompleted);
  36:      }
  37:   
  38:      public void BeginFetch(object criteria, object userState)
  39:      {
  40:          DataPortal.BeginFetch(criteria, FetchCompleted, userState);
  41:      }
  42:   
  43:      public void BeginFetch(object criteria)
  44:      {
  45:          DataPortal.BeginFetch(criteria, FetchCompleted);
  46:      }
  47:   
  48:      public void BeginFetch()
  49:      {
  50:          DataPortal.BeginFetch(FetchCompleted);
  51:      }
  52:   
  53:      public void BeginUpdate(T obj, object userState)
  54:      {
  55:          DataPortal.BeginUpdate(obj, UpdateCompleted, userState);
  56:      }
  57:   
  58:      public void BeginUpdate(T obj)
  59:      {
  60:          DataPortal.BeginUpdate(obj, UpdateCompleted);
  61:      }
  62:   
  63:      public T Create()
  64:      {
  65:          return DataPortal.Create<T>();
  66:      }
  67:   
  68:      public TC CreateChild<TC>()
  69:      {
  70:          return DataPortal.CreateChild<TC>();
  71:      }
  72:   
  73:      public TC CreateChild<TC>(params object[] parameters)
  74:      {
  75:          return DataPortal.CreateChild<TC>(parameters);
  76:      }
  77:   
  78:      public T Create(object criteria)
  79:      {
  80:          return DataPortal.Create<T>(criteria);
  81:      }
  82:   
  83:      public async Task<T> CreateAsync(object criteria)
  84:      {
  85:          return await DataPortal.CreateAsync<T>(criteria);
  86:      }
  87:   
  88:      public async Task<T> CreateAsync()
  89:      {
  90:          return await DataPortal.CreateAsync<T>();
  91:      }
  92:   
  93:      public event EventHandler<DataPortalResult<T>> CreateCompleted;
  94:   
  95:      public void Delete(object criteria)
  96:      {
  97:          DataPortal.Delete<T>(criteria);
  98:      }
  99:   
 100:      public Task DeleteAsync(object criteria)
 101:      {
 102:          return DataPortal.DeleteAsync<T>(criteria);
 103:      }
 104:   
 105:      public event EventHandler<DataPortalResult<T>> DeleteCompleted;
 106:   
 107:      public T Execute(T obj)
 108:      {
 109:          return DataPortal.Execute<T>(obj);
 110:      }
 111:   
 112:      public async Task<T> ExecuteAsync(T command)
 113:      {
 114:          return await DataPortal.ExecuteAsync<T>(command);
 115:      }
 116:   
 117:      public event EventHandler<DataPortalResult<T>> ExecuteCompleted;
 118:   
 119:      public T Fetch()
 120:      {
 121:          return DataPortal.Fetch<T>();
 122:      }
 123:   
 124:      public T Fetch(object criteria)
 125:      {
 126:          return DataPortal.Fetch<T>(criteria);
 127:      }
 128:   
 129:      public async Task<T> FetchAsync(object criteria)
 130:      {
 131:          return await DataPortal.FetchAsync<T>(criteria);
 132:      }
 133:   
 134:      public async Task<T> FetchAsync()
 135:      {
 136:          return await DataPortal.FetchAsync<T>();
 137:      }
 138:   
 139:      public TC FetchChild<TC>()
 140:      {
 141:          return DataPortal.FetchChild<TC>();
 142:      }
 143:   
 144:      public TC FetchChild<TC>(params object[] parameters)
 145:      {
 146:          return DataPortal.FetchChild<TC>(parameters);
 147:      }
 148:   
 149:      public event EventHandler<DataPortalResult<T>> FetchCompleted;
 150:   
 151:      public ContextDictionary GlobalContext
 152:      {
 153:          get { return ApplicationContext.GlobalContext; }
 154:      }
 155:   
 156:      public T Update(T obj)
 157:      {
 158:          return DataPortal.Update<T>(obj);
 159:      }
 160:   
 161:      public async Task<T> UpdateAsync(T obj)
 162:      {
 163:          return await DataPortal.UpdateAsync<T>(obj);
 164:      }
 165:   
 166:      public event EventHandler<DataPortalResult<T>> UpdateCompleted;
 167:   
 168:      public void UpdateChild(object child)
 169:      {
 170:          DataPortal.UpdateChild(child);
 171:      }
 172:   
 173:      public void UpdateChild(object child, params object[] parameters)
 174:      {
 175:          DataPortal.UpdateChild(child, parameters);
 176:      }
 177:  }

This object factory implementation requires that our IoC container understand the concept of generics and the type of object that we pass in must implement CSLA's IMobileObject interface.  The IBusinessBase, IBusinessListBase, IReadOnlyBase, IReadOnlyListBase and ICommandObject all implement this interface and will be usable for our custom object factory.  If I always make sure to use the IObjectFactory interface to resolve out my DataPortal call I will be able to mock the entire thing out when writing unit tests.

To create our concrete classes we can follow this pattern:

   1:  public class TestBusinessBase : BusinessBase<TestBusinessBase>, ITestBusinessBase
   2:  {
   3:      public static readonly PropertyInfo<int> IdProperty = RegisterProperty<int>(c => c.Id);
   4:      public int Id
   5:      {
   6:          get { return GetProperty(IdProperty); }
   7:          private set { LoadProperty(IdProperty, value); }
   8:      }
   9:   
  10:      public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(c => c.Name);
  11:      public string Name
  12:      {
  13:          get { return GetProperty(NameProperty); }
  14:          set { SetProperty(NameProperty, value); }
  15:      }
  16:   
  17:      public void SomeMethod(string someParameter)
  18:      {
  19:          throw new NotImplementedException();
  20:      }
  21:   
  22:      public static ITestBusinessBase CreateTechBusinessBase()
  23:      {
  24:          return IoC.Container.Resolve<IObjectFactory<ITestBusinessBase>>().Create();
  25:      }
  26:   
  27:      public async static Task<ITestBusinessBase> GetTestBusinessBaseByIdAsync(int id)
  28:      {
  29:          return await IoC.Container.Resolve<IObjectFactory<ITestBusinessBase>>().FetchAsync(id);
  30:      }
  31:  }

This is a sample of an implementation for our BusinessBase interface and all the stereotypes will generally look the same.  There are a few of things to notice here:

- Our concrete class still inherits from CSLA's BusinessBase class as well as our ITestBusinessBase interface
- Using the static factory methods will tie anything using it to the concrete class TestBusinessBase to locate the factory method
- We always return our interface instead of the concrete class type
- We use the global IoC class to resolve by interface instead of calling the concrete object factory or the concrete TestBusinessBase.  This allows us to return any implementation of the IObjectFactory and/or ITestBusinessBase we desire from the IoC container.  This will be very useful when it comes to creating unit tests.

If you don't like the idea of using the static factory methods, any code that would call the factory method can call the object factory instead.  The downside of this is if we have our factory methods abstract out knowledge of the criteria and parameters allowed to make it easy for the consumers of our classes.  The person using our classes will instead need to know the particulars of the allowed parameters for the factory.  For the above class we could call the following instead of calling the GetTestBusinessBaseByIdAsync factory method:

   1:  await IoC.Container.Resolve<IObjectFactory<ITestBusinessBase>>().FetchAsync(id);

To understand what we need to do next we have to understand a little about how CSLA's data portal works.  When we ask it to create, fetch or save an object it creates an instance of that type (unless using the object factory pattern which is not covered here).  The type to create is determined by the type set in the data portal generic.  For example if I call the following:

   1:  DataPortal.Create<TestBusinessBase>()

The CSLA data portal will attempt to create an instance of the TestBusinessBase object and then call it's DataPortal_Create method.  But that's not what our code ends up doing.  What our code ultimately will call on the CSLA data portal is this:

   1:  DataPortal.Create<ITestBusinessBase>()

CSLA's data portal won't know what concrete class to create in this case.  ITestBusinessBase is just an interface.  So what do we do?  This is where CSLA's IDataPortalActivator interface comes into play.  This interface allows us to do two things:

- Tell CSLA what instance to create (CreateInstance method)
- Set any properties on that instance after it is created (InitializeInstance method)

There are a few items to note here.  The CreateInstance method only receives one parameter, the type that is being requested.  In normal CSLA operation this would be a concrete type but in our case we are going to be passed in the ITestBusinessBase interface.  There is an implication to this as we do not have access to any other parameters sent along with the data portal call.  This means we only have a few ways to create the required instance from the type information:

- A convention that given the type of the interface we are able to determine the concrete type we want to create

   1:  public object CreateInstance(Type requestedType)
   2:  {
   3:      if (requestedType == null)
   4:      {
   5:          throw new ArgumentNullException("requestedType");
   6:      }
   7:   
   8:      return requestedType.IsInterface ? CreateConcreteTypeByConvention(requestedType) : Activator.CreateInstance(requestedType);
   9:  }

- Pulling something out of global scope, such as an IoC container, to resolve out the concrete type we want to create

   1:  public object CreateInstance(Type requestedType)
   2:  {
   3:      if (requestedType == null)
   4:      {
   5:          throw new ArgumentNullException("requestedType");
   6:      }
   7:   
   8:      return requestedType.IsInterface ? IoC.Container.Resolve(requestedType) : Activator.CreateInstance(requestedType);
   9:  }

The InitializeInstance method allows us to set and initialize properties on the newly created instance but it only receives a reference to the instance of the class that was created in the CreateInstance method.  Like the CreateInstance method, any information that we sent along with the initial data portal request is not directly available to us.  For example, we cannot pass in the IoC container as a parameter to a factory method that uses the CSLA data portal and then use that parameter in the CreateInstance method to create an instance of the class we want without somehow storing it in a global context. 

CSLA does provide a way to set up parameters in a global context that can be used in the CreateInstance and InitializeInstance methods.  Implementing the IInterceptDataPortal interface will provide us with methods we can use for this purpose. This interface has Initialize and Complete methods that happen at the start of and end of our data portal call and allow us to set up and then clean up any global context needed.  Be aware that the are some complications around the cleanup, particularly if an error occurs in the request.  I won't be covering using the IInterceptDataPortal interface in this blog post.  The best person to ask about using it is Jason Bock.

A sample IDataPortalActivator class may look like this:

   1:  public sealed class ObjectActivator : IDataPortalActivator
   2:  {
   3:      public object CreateInstance(Type requestedType)
   4:      {
   5:          if (requestedType == null)
   6:          {
   7:              throw new ArgumentNullException("requestedType");
   8:          }
   9:   
  10:          return requestedType.IsInterface ? IoC.Container.Resolve(requestedType) : Activator.CreateInstance(requestedType);
  11:      }
  12:   
  13:      public void InitializeInstance(object obj)
  14:      {
  15:      }
  16:  }


To tell CSLA to use our new activator instead of the default CSLA implementation call the following line in code:

   1:  Csla.ApplicationContext.DataPortalActivator = new ObjectActivator();

Notice this is also a service locator pattern.  I want to reiterate this idea.  Like ASP MVC, CSLA is built on top of service locators.  This call is no different.  In order to use frameworks like ASP MVC or CSLA you have to buy into the idea that the service locator pattern is sometimes desirable.

In this post we learned how to create and pass around CSLA objects as interfaces instead of concrete classes using the CSLA data portal.  This will allow us much greater flexibility when it comes to unit testing and mocking.  In my next post we will talk about how to similarly abstract away data access calls to assist in unit testing and mocking.

Saturday, November 23, 2013

Windows Azure SQL Databases, Cost Effective or Not?

Last week I gave an Windows Azure presentation at Modern Apps Live in Orlando.  The session itself wasn't well attended and that matches many of my past experiences with Azure presentations.  I spoke to several people afterwards and it seems that much of the disinterest around Azure has to do with its perceived high cost when comparing it to alternatives.

To some extent this is Microsoft's fault, when they came out with the service initially it wasn't all that well priced.  But for the most part that has changed and Azure is a much better deal than people realize, particularly when looking at factors around redundancy.  For example, there are few ways to quickly and cheaply get a redundant T-SQL database up than by using a Windows Azure SQL Database (WASD).

Companies usually have about three options here.  They can use a private cloud (either existing or build a new one), they can use some sort of IAAS provider like Rackspace (or use Azure IAAS), or they can use a PAAS like WASD.

The private cloud cost comparison is harder to quantify as there are so many situational specific factors that need to be understood in the calculation.  It is usually true that for companies who have existing private clouds it is cheaper to leverage a sunk investment than to move to an IAAS or PAAS SQL solution in the short term.  I want to reiterate; in the short term.  That is because in the short term much of the cost involved in creating that private cloud is sunk.  In the long term (five year horizon) that calculation may change as hardware needs to be refreshed and the amount of services  you plan on deploying to your private cloud will influence the amount of hardware you will need to keep up to date to continue your private cloud investment.  This is an area where momentum tends to come into play that is to say, the path of least resistance is for IT managers to continue to refresh their private cloud infrastructure than to come up with a plan for moving a portion of their services into a hybrid cloud.

In general, if you have a private cloud and want to do a long term analysis on the benefits of moving SQL Services to a hybrid or public cloud these are some of the factors you want to keep in mind.
  • If I move some of my services to a hybrid/public cloud what will my data transfer services cost me in the cloud vs. how much do they cost me now?  Corollary to this is the question of should I move applications that use the data into the cloud as well to limit that data transfer cost?  Remember, to do an apples to apples comparison here, moving around data on your current infrastructure has an associated cost as well (hardware to deal with the amount of data flowing through the network, dark fiber between facilities, external lines that have a data charge for lighting buildings or employees in the field, etc.)  The cost of data transfer is most likely the greatest single monetary factor in this equation.
  • If you move some portion of your services to the cloud, can you do a lower investment in hardware in your private cloud due to the lower need for services in your own facilities?
  • What kind of data do you have and what are the risks between maintaining it in different locations?  The common example is that HIPPA generally is not used in public clouds, though Azure has been working on solutions for that too: http://www.eweek.com/c/a/Health-Care-IT/Microsoft-Adds-HIPAA-Compliance-in-Windows-Azure-for-Cloud-Health-Data-446671/
  • Do I need to have a solution with geographically diverse databases and if so, what are my requirements behind how often the data needs to be kept in sync?  WASD can be set up in many different geographic regions and kept in sync, over time.  The sync interval can be set as low as every five minutes but due to the hub and spoke model even that may take as long as 10 minutes for data changes to be distributed from one spoke to another.
  • How much does your OS licensing cost you?
  • Can the applications that use the database use SQL security instead of Windows integrated security?  WASD only supports the SQL security model.
  • How much does your infrastructure cost you and what are the opportunity costs associated with having infrastructure personnel working machines with SQL databases instead of the many other mission critical items they could be focusing on?  Do you need the same amount of infrastructure resources, particularly as the company grows, etc.?
  • Do you have SLA requirements?  Currently the WASD offer 99.9% monthly uptime.  Many companies require more. Having said that, in my experience very few companies actually maintain greater than 99.9% when doing an analysis of their internal data center operations.  This is an area where companies may have to analyze what their internal capabilities really are.
  • What are your redundancy requirements?  This is one where WASD are hard to beat and give a benefit few people recognize.  If you have an instance of a WASD in a Azure data center you are getting that plus three redundant instances; one primary redundant instance and two secondary.  If your main instance, or one (or more) of the redundant instances go down, Azure will use the others to continue uninterrupted service and bring up more redundant instances in the background.  The net effect is that it is very difficult to take down a WASD instance without an entire data center or the Azure service in general going down (which has happened twice that I can recall).
One thing you may notice is missing from my list; that is DBAs.  You will likely need the same number of DBAs if you host your databases in your private cloud, in a public cloud through IAAS or using a PAAS offering like WASD.  We know comparing the cost of a private cloud is highly situational, but what about looking at IAAS vs. a PAAS like WASD?  That is much clearer, and in most cases WASD will be doing IAAS at a company like Rackspace.  If you've determined that moving a SQL Service instance from your internal private cloud to an IAAS service, in many cases it may be less expensive to take it one step further and go to WASD.

Let's look at this comparison.  For information about assumptions, we have about 60 GB of data of which our average outbound data per month is 2000 GB, increasing 10% yearly.  Also for the Rackspace offering we set up two servers is an active/passive SQL cluster to get some level of redundancy but still less than what we get with WASD.  If that's the case, we end up with something like this:

Windows Azure Year 1 Year 2 Year 3 Year 4 Year 5 Total
Cost WASD/Year $1,510.56 $1,570.44 $1,630.44 $1,690.32 $1,750.32 $8,152.08
Cost of outbound data $2,880.00 $3,168.00 $3,484.80 $3,833.28 $4,216.61 $17,582.69
Total $4,390.56 $4,738.44 $5,115.24 $5,523.60 $5,966.93 $25,734.77

IAAS (Rackspace) Year 1 Year 2 Year 3 Year 4 Year 5 Total
Cost of server licensing $155.40 $0.00 $0.00 $180.00 $0.00 $335.40
Cost of SQL licensing $678.00 $0.00 $0.00 $711.90 $0.00 $1,389.90
Cost of data center $1,401.60 $1,401.60 $1,401.60 $1,401.60 $1,401.60 $7,008.00
Cost of IT labor $480.00 $494.40 $509.23 $524.51 $540.24 $2,548.39
Cost of outbound data $2,880.00 $3,168.00 $3,484.80 $3,833.28 $4,216.61 $17,582.69
Total $5,595.00 $5,064.00 $5,395.63 $6,651.29 $6,158.45 $28,864.37

Of course there are many factors that can cause these numbers to change.  For example, we can say that the SQL instance doesn't need to be redundant like it is with WASD.  Also Rackspace's outgoing data charges decrease the more data you use while WA does not (perhaps something MS should change to stay competitive).  The point of the exercise is to realize that prima facie the Windows Azure services are not more expensive than competitive offerings.  The services offer other benefits that I have not mentioned here but they are worth doing a serious analysis on, both from a cost and a feature perspective.

If you do, or do not, think Windows Azure services are cost effective, or even if you don't know I'd be interesting in speaking with you.

Friday, November 1, 2013

Angular Promises in TypeScript

If you're like me and love typed languages, TypeScript seems like a great thing and it is.  Though there are some complications to using it along with some of the existing frameworks that are out there.  A lot of this comes from using modules and classes in TypeScript, which you probably are if you are using typeScript in the first place.  When using TypeScript and Angular it can sometimes be hard to get access to things like Angular's $scope deep within the bowels of your classes.

Recently I was working with Azure and handling the asynchronous request callback using an Angular promise.  This presented me with a couple of difficulties:

  • When calling .resolve on the deferral, it was never firing the .when statement on the code that was holding the promise so I never got may data loaded correctly from my factory
  • Inside the deferral callback code in a class, any calls to the classes properties using the 'this' operator were failing with an undefined or null reference error
What to do?  Here was my original non working code:

Calling code:
this.dataAccess.BeginGetRegistrations().then(function (result: Classes.RegistrationDTO[]) {
    for (var i in result) {
        var registrationDTO: Classes.RegistrationDTO = result[i];
        var registration: Registration = new Registration(registrationDTO.Id, this.dataAccess);
        registration.LoadRegistration(registrationDTO.ScreenName, registrationDTO.Email, registrationDTO.Zip, registrationDTO.Gender, registrationDTO.BirthDate);
        this.Add(registration);
    }
});

Asynchronous function in my data access class:
public BeginGetRegistrations(): ng.IPromise<Classes.RegistrationDTO[]>{
    var deferral = this.service.defer<Classes.RegistrationDTO[]>();
    var registrations = DataAccess.client.getTable('Registration');

    registrations.read().done(function (results) {
        var returnValue: Classes.RegistrationDTO[] = [];
        var registration: Classes.RegistrationDTO;
        for (var i in results) {
            var result = results[i];
            registration = current.LoadResult(result);
            returnValue.push(registration);
        }
        deferral.resolve(returnValue);
    }, function(err) {
        throw err.toString();
    });
    return deferral.promise;;
}

I did a little digging around it seemed obvious.  The call to resolve on the deferral needs to happen in a context that Angular is aware of.  In this case, calling resolve inside $apply method on the $rootScope should solve it so the .when statement on the calling code fires.  Since I was way down in the bowls of a class inside a module I had Angular inject the $rootScope into my factory which in turn set it inside my data access class on creation (constructor).  Now my data access class has a reference to the $rootScope in a class level variable called scope.

I rewrote my code hoping to get the .when to fire like this:
public BeginGetRegistrations(): ng.IPromise<Classes.RegistrationDTO[]>{
    var deferral = this.service.defer<Classes.RegistrationDTO[]>();
    var registrations = DataAccess.client.getTable('Registration');

    registrations.read().done(function (results) {
        var returnValue: Classes.RegistrationDTO[] = [];
        var registration: Classes.RegistrationDTO;
        for (var i in results) {
            var result = results[i];
            registration = current.LoadResult(result);
            returnValue.push(registration);
        }
        this.scope.$apply(deferral.resolve(returnValue));
    }, function(err) {
        throw err.toString();
    });
    return deferral.promise;;
}

As soon as I did this, the second problem raised its head.  That is, I couldn't get access to the 'this' keyword and was failing with an undefined or null reference.  This problem manifested in both the BeginGetRegistration method and the calling code.  The solution was simple.  In each of these methods set a local variable equal to the class level 'this' variable so the callback function has access to it and all was well with the world.  My new corrected and working functions:

Calling code:
var current: any = this;
this.dataAccess.BeginGetRegistrations().then(function (result: Classes.RegistrationDTO[]) {
    for (var i in result) {
        var registrationDTO = result[i];
        var registration: Registration = new Registration(registrationDTO.Id, current.dataAccess);
        registration.LoadRegistration(registrationDTO.ScreenName, registrationDTO.Email, registrationDTO.Zip, registrationDTO.Gender, registrationDTO.BirthDate);
        current.Add(registration);
    }
});

Asynchronous function in my data access class:
public BeginGetRegistrations(): ng.IPromise<Classes.RegistrationDTO[]>{
    var deferral = this.service.defer<Classes.RegistrationDTO[]>();
    var registrations = DataAccess.client.getTable('Registration');
    var current: any = this;

    registrations.read().done(function (results) {
        var returnValue: Classes.RegistrationDTO[] = [];
        var registration: Classes.RegistrationDTO;
        for (var i in results) {
            var result = results[i];
            registration = current.LoadResult(result);
            returnValue.push(registration);
        }
        current.scope.$apply(deferral.resolve(returnValue));
    }, function(err) {
        throw err.toString();
    });
    return deferral.promise;;
}

With these fixes in place my Azure mobile code was loading beautifully, asynchronously and Angular binding was handling the data coming back and displaying on the UI exactly as it should.