Quantcast
Channel: C# – Falafel Software Blog
Viewing all articles
Browse latest Browse all 54

Azure Mobile Apps: Writing a Fast Custom DomainManager, Part 1

$
0
0

My last post took you on a journey with me as I analyzed the Azure Mobile App default base entity class and talked about some of the things I saw there. To summarize, I was most disturbed to note that the default choice of primary key was a Unicode string, which as a database and query guy immediately raised all sorts of alarms, flags, flashing lights, klaxons, sirens… well, you get the idea. Strings make inefficient keys to begin with, and Unicode keys literally doubly so. I found a MSDN post that seemed like it might solve the problem with a custom DomainManager, but was dissatisfied with the SQL it emitted. However, I thought I could figure out how to work around it, and you know what? I was right. I found lots more interesting stuff along the way, too! Let’s just dive right in, shall we?

Getting Started

The first thing to do when creating a custom DomainManager is to decide which class to inherit from. If your model classes inherit from EntityData with its ungainly Unicode string key, you use the EntityDomainManager, which derives from DomainManager. The SimpleMappedEntityDomainManager from the MSDN post I referenced last time derives from MappedEntityDomainManager. Already repulsed by the queries being emitted by SimpleMappedEntityDomainManager, my initial impulse was to disassociate as much as possible from it, and so inherit directly from DomainManager, but it quickly became obvious that this would create a lot of unnecessary work, so I decided to try inheriting from MappedEntityDomainManager instead. This turned out to be the right choice, because while it is not well-documented, the MappedEntityDomainManager is in fact well designed to make it very easy to perform custom mappings while avoiding the query performance pitfalls of the implementation of SimpleMappedEntityDomainManager. As you will see, you will actually be able to do all of this while also writing less code than SimpleMappedEntityDomainManager.

The Absolute Minimum Code Necessary

Declare a class that inherits from a MappedEntityDomainManager and then use the Smart Tag that should appear on MappedEntityDomainManager to ‘Implement abstract class’. Code that looks like this will appear:

public class CustomEntityDomainManager<TData, TModel, TKey> : MappedEntityDomainManager<TData, TModel>
    where TData: class, ITableData, new()
    where TModel : class
{
    public override Task<bool> DeleteAsync(string id)
    {
        throw new NotImplementedException();
    }

    public override SingleResult<TData> Lookup(string id)
    {
        throw new NotImplementedException();
    }

    public override Task<TData> UpdateAsync(string id, Delta<TData> patch)
    {
        throw new NotImplementedException();
    }
}

That’s right, you only need to implement three methods to have a fully functional custom DomainManager! I added the TKey generic type parameter for reasons that will become clear later, so just ignore that for now. The main thing to pay attention to here is the method signatures. They all accept a string ID, because that’s the standard way that the Azure Mobile client SDKs interact with TableControllers. It’s up to you to perform the mapping from the string representation of your table keys to the actual key, update the store, and map the results into an ITableData DTO. This is already pretty nice, because the amount of work you need to do is already pretty narrow in scope, but it gets even better. MappedEntityDomainManager provides some additional utilities that can make this job even simpler! There are two main categories as I see them: Key Mapping utilities, and Entity Manipulation utilities.

Key Mapping Utilities

The first category of utilities provided by MappedEntityDomainManager assists with the task of converting the string ID into the type of the key used by your model. There are two methods for this purpose: GetKey and GetCompositeKey. They each have their own little quirks, so let’s look at each one individually.

GetKey

The full signature of GetKey is as follows:

protected virtual TKey GetKey<TKey>(string id, CultureInfo culture)

There’s an overload that passes the invariant culture by default as the second parameter. All this method does is put a generic type parameter facade over calling Convert.ToType(), so it just provides a slightly nicer syntax to perform key conversion. If your custom entity uses a single-column key, look no further than this method to get the job done.

GetCompositeKey

The signature of GetCompositeKey is simpler:

protected virtual CompositeTableKey GetCompositeKey(string id)

But there’s more going on under the hood. This method actually defers to the CompositeTableKey class to implement parsing a composite key. The format that the parser expects is: \segment1\,\segment2[,…n]. The resulting CompositeTableKey instance contains the key segments in the Segments property. These segments are still strings, so you still need to convert them to the appropriate type, perhaps by leaning on GetKey.

An Alternative

Another approach that I experimented with before discovering the existence of these two methods was to create a new TData object, assign the string id to its Id property, then use AutoMapper to use the existing registered mapping to translate the TData object into a TModel object, and then use the key property(s) to implement DeleteAsync, Lookup, and UpdateAsync. This approach is attractive because it puts more control into the hands of the consuming class, but I have a feeling that the MappedEntityDomainManager is built on the assumption that keys are passed in a way that are more simply mapped, so if you choose to pursue this course, be mindful that you may encounter complications down the line. This implementation tends to be a bit less flexible as well, but it might fit certain specific scenarios.

Halfway there!

Simply knowing what methods you need to implement and what tools are provided by the framework has already taken a daunting task and made it seem much more approachable. In the next post, I’ll go into detail on additional tools provided that nearly turn the implementation of DeleteAsync, Lookup, and UpdateAsync into one-liners, and then I’ll show how to initialize and test a TableController that uses a custom MappedEntityDomainManager, profile the resulting SQL, and discuss some of the important differences from the SQL that was generated by the SimpleMappedEntityDomainManager from the MSDN post.

The post Azure Mobile Apps: Writing a Fast Custom DomainManager, Part 1 appeared first on Falafel Software Blog.


Viewing all articles
Browse latest Browse all 54

Trending Articles