Author: James

Azure, PowerShell and DLL hell

It’s great that Azure is supported so extensively within Windows PowerShell – it really helps with automating builds and adopting a continual delivery / DevOps approach however eventually, in my experience, you’ll find yourself wanting to supplement what’s available from Microsoft with some Cmdlets of your own. Sure you can access .Net from PowerShell but sometimes C# is just more expressive and maintainable.

Of course this is simple enough to do and an example of implementing Cmdlets that use the Storage and Service Bus SDKs to create and configure resources can be found in the Application Support framework (here’s a direct link to the relevant project).

However I guarantee you that given the pace of change in the Azure space then at some point you’ll hit a DLL binding issue. Your Cmdlet will reference a different version of the Storage DLL or you’ll be using NewtonSoft.Json v7 while the Storage SDK is using v6 or vice versa and you’ll get one of those delightful can’t find DLL issues. And here I was thinking that at one point .Net was supposed to solve DLL hell!

Fortunately there’s a fairly simple solution to this: the PowerShell executable is a .Net application like any other and you can add binding redirects to a powershell.exe.config file. On a clean Windows machine this file doesn’t exist but you can create it easily enough using notepad or your text editor of choice. If you’re using a 32-bit operating system then PowerShell can be found in the folder:

C:\Windows\System32\WindowsPowerShell\v1.0

Or on a 64-bit operating system in:

C:\Windows\SysWOW64\WindowsPowerShell\v1.0

In that folder either create a new file or edit the existing one – you’ll probably need to run your text editor with Administrator privileges. As an example my current powershell.exe.config file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Hope that helps with any PowerShell binding issues.

AccidentalFish.ApplicationSupport v2.1.0 Released

I’ve just pushed to Nuget the latest version of this framework. Full release notes are available here. The main addition is the support for IoC containers other than Unity – I’ve added support for Ninject and Autofac with this release however I’ve also improved the component host with a default restart handler and made a set of bug fixes.

I’ve also been working on tutorial / getting started documentation and you can find the first part of this here.

As ever I’d love to hear any feedback you might have either here or over on the GitHub Issues page.

AccidentalFish.Application Support v2.0.0 Release

This is now available in both GitHub and NuGet. There have been a large number of changes mostly to make the naming consistent throughout the framework and also documentation has been added to all public interfaces in the AccidentalFish.ApplicationSupport.Core assembly / package.

Release notes are available, the API reference, and documentation site updated.

Any issues please let me know here or on GitHub.

AccidentalFish.ApplicationSupport v2.0.0

As part of my documentation push I’m also dealing with some unresolved naming issues and inconsistencies I’ve noticed since releasing v1.0.0.

As addressing some of this means breaking changes, and following the semver rules, I’ll be releasing this as v2.0.0 of the framework in due course.

I’m tracking the changes in a release note as I make them and you can already see that here if you want a view of what is coming.

Azure Notification Hub – Double Message Gotcha

I recently worked on a piece of Azure hosted software that was required to send a large volume of push notifications to mobile devices and so decided to give Azure Notification Hubs a whirl.

On the whole I found it to be pretty easy to set up and get going with and very well documented with walkthroughs for most scenarios (both server side and device) across all the major platforms.

But, and you knew there was a but coming didn’t you?, I did come across one major gotcha while building an implementation based off the tutorial on sending notifications from your server.

After implementing this and doing a bit of debugging I was finding that every time I sent a message from the server to the device my device was responding to it multiple times. Due to how devices and the registration process work you do have to be careful to ensure that your device isn’t already registered with the notification hub and Microsoft themselves show you how to do this in this code snippet:

public class DeviceRegistration
{
    public string Platform { get; set; }
    public string Handle { get; set; }
    public string[] Tags { get; set; }
}
 
// POST api/register
// This creates a registration id
public async Task<string> Post(string handle = null)
{
    string newRegistrationId = null;
 
    // make sure there are no existing registrations for this push handle (used for iOS and Android)
    if (handle != null)
    {
        var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100);
 
        foreach (RegistrationDescription registration in registrations)
        {
            if (newRegistrationId == null)
            {
                newRegistrationId = registration.RegistrationId;
            }
            else
            {
                await hub.DeleteRegistrationAsync(registration);
            }
        }
    }
 
    if (newRegistrationId == null) 
        newRegistrationId = await hub.CreateRegistrationIdAsync();
 
    return newRegistrationId;
}
 
// PUT api/register/5
// This creates or updates a registration (with provided channelURI) at the specified id
public async Task<HttpResponseMessage> Put(string id, DeviceRegistration deviceUpdate)
{
    RegistrationDescription registration = null;
    switch (deviceUpdate.Platform)
    {
        case "mpns":
            registration = new MpnsRegistrationDescription(deviceUpdate.Handle);
            break;
        case "wns":
            registration = new WindowsRegistrationDescription(deviceUpdate.Handle);
            break;
        case "apns":
            registration = new AppleRegistrationDescription(deviceUpdate.Handle);
            break;
        case "gcm":
            registration = new GcmRegistrationDescription(deviceUpdate.Handle);
            break;
        default:
            throw new HttpResponseException(HttpStatusCode.BadRequest);
    }
 
    registration.RegistrationId = id;
    var username = HttpContext.Current.User.Identity.Name;
 
    // add check if user is allowed to add these tags
    registration.Tags = new HashSet<string>(deviceUpdate.Tags);
    registration.Tags.Add("username:" + username);
 
    try
    {
        await hub.CreateOrUpdateRegistrationAsync(registration);
    }
    catch (MessagingException e)
    {
        ReturnGoneIfHubResponseIsGone(e);
    }
 
    return Request.CreateResponse(HttpStatusCode.OK);
}

You’ll notice the comment in the built of the Post action about making sure their are no existing registrations for the push handle. The handle is a token you obtain from the device and use as illustrated as part of the registration process.

The problem is – this code sample doesn’t work.

I learned the hard way that when the registration is created (in the Put action) the notification hub converts the handle to all upper case text. The handle from my device (which I obtained using the Cordova PushPlugin – I was working in Ionic) contained a mix of lower case letters and numbers.

When you subsequently search for registrations that match the handle (var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100)) it performs a case sensitive search and none of your previous registrations will be found.

The result is that you can find yourself registering the same device token multiple times against different registration IDs and when you do a message send it is sent multiple times – multiple registrations == multiple sends.

If you suspect you might have a similar problem you can enumerate all registrations with the GetAllRegistrationsAsync method on the NotificationHubClient.

Other than that, and as I said earlier, my experience with the Notification Hub was really very smooth.

AccidentalFish Application Support Updates

A quick post with a few bits of news regarding my lightweight application framework.

Logger

Yesterday I pushed out a new version of the packages that contain an updated logger that will work alongside my Owin middleware for HTTP logging and correlation ID attachment.

If you use that middleware package, and an appropriate filter (Web API or MVC) in a project using the logger then everything should just work.

Versioning

I’ve not been strict enough over the versioning of this framework and I’m going to tighten this up by adopting the Semver format and guidelines. I am aware of a few, minor, upcoming breaking changes as I’ve realised I’ve got some naming inconsistencies in the interfaces (particularly around the use of async) – at least by adopting Semver it will be clear when I make those changes.

Documentation

The long promised documentation is now underway – something of a minor miracle as I’m always distracted by Visual Studio! I’m hosting it on GitHub Pages, go check it out. It’s early days but I’m hoping to make fairly short work of getting started guides so at least there’s a clear way into the framework.

I’m writing the documentation using Markdown and that’s getting translated into HTML on GitHub Pages via Jekyll. I’ve not used Jekyll before but it’s pretty simple to get going with and coupled with Markdown seems to be a neat solution to creating verbose documentation. I’ll be producing API reference documentation using C#s XML comments and Sandcastle.

Http Logging and Correlation IDs

I’ve recently pushed out some new open source for HTTP logging / tracing and alongside that support for adding correlation IDs to http calls and tracking them across MVC and Web API applications.

It’s fully documented and can be found in GitHub and on NuGet. The logger is independent of storage mechanism however I’ve currently only created a repository for Azure. I’ll probably add a SQL repository shortly.

The NuGet packages are entirely free standing other than the minimal Microsoft dependencies required.

I’m currently working on adding correlation ID support to the logging framework contained within the wider AccidentalFish.ApplicationSupport framework and I expect that to roll out early next week.

Alongside this I’m having a bit of a documentation push for all my open source. Other than Markdown and Sandcastle I’d be very interested in hearing how others have approached creating large amounts of technical documentation in the Microsoft space.

As ever feedback and issue reports are very welcome.

Azure Cloud Roles with .Net 4.5.2 and .Net 4.6

If, like me, you’ve been quietly tearing your hair out about the lack of support for .Net 4.5.2 in Azure Cloud Roles (and now .Net 4.6) for the last year or so then tear your hair out no longer!

I’d missed it but support for this shipped in the Azure SDK 2.6. You still have to install the .Net framework yourself as a startup task but there are some pretty clear instructions provided for doing that here that at the time of writing uses .Net 4.5.2 as an example.

According to the release notes 4.6 is also supported but I’ve not yet had an opportunity to try that.

AngularJS, IdentityServer3 and OAuth2 Plugin Sample

By popular(ish) demand I’ve published to GitHub a sample that demonstrates using my OAuth 2 Angular plugin (also hosted on GitHub) requesting tokens from IdentityServer3 and using them to access protected Web API resources.

The sample can be found on GitHub and should be pretty easy to get running as long as you have the pre-reqs (npm, git, grunt and bower primarily):

  1. Open the SLN file in Visual Studio and start both projects.
  2. Open a NodeJS command prompt and navigate to the UI folder.
  3. Type “bower install” to install the plugins.
  4. Type “grunt serve” to run the Angular app.

The identity server is prewired with a single user account details as follows:

Username: auser
Password: password

It should be noted that this is illustrative code, particularly in the C# projects, and it’s been written as such. I didn’t want to cloud the example with dependency injectors and other such components.

Thanks to everyone for their comments, questions, and feedback on the plugin both here and on GitHub.

AccidentalFish ApplicationSupport – v1.0.0

As per my previous post I’m spending some time on my application framework – I’m aware of this getting used, by myself and others, in a variety of projects and some of the flaws in the code as it stands now are starting to hurt. Since I first put it together the Azure libraries have also come on a long way and this has led to some friction.

That being the case I’m taking this oppurtunity to revisit the framework with a number of objectives:

  1. Reduce the number of dependencies. Even the core assembly had accumulated around 10 NuGet dependencies including Azure storage, Entity Framework, Unity, AWS and SendGrid.
  2. Removal of the Enterprise Library Transient Fault framework.
  3. Support for dependency injectors other than Unity.
  4. Switch to NewtonSoft Json for serialization.
  5. Documentation and samples.
  6. Move to the “new” way of restoring packages.

This does mean a bunch of breaking changes but I think they’re worth making to achieve the above.

I’ve got a compiling first stab at v1.0.0 in GitHub. I’ll be testing this in an upcoming project and dropping the packages into the NuGet prerelease channel.

Contact

  • If you're looking for help with C#, .NET, Azure, Architecture, or would simply value an independent opinion then please get in touch here or over on Twitter.

Recent Posts

Recent Tweets

Invalid or expired token.

Recent Comments

Archives

Categories

Meta

GiottoPress by Enrique Chavez