Sunday, February 15, 2015

Enabling GZip Compression in WebAPI and Owin

Interesting little challenge today. I’m building an application that uses Web API and will run in an OWIN SelfHost and my payload as big enough to warrant GZip Compression. But, since my app is running as an Owin Selfhosted api, I can’t use IIS Compression.

So I created a little compression attribute. Seems to work great.

   1: namespace eVision.AppShaping.Handlers.Controllers
   2: {
   3:     using System.IO.Compression;
   4:     using System.Linq;
   5:     using System.Net.Http;
   6:     using System.Threading;
   7:     using System.Threading.Tasks;
   8:     using System.Web.Http.Filters;
   9:  
  10:     internal class GzipCompressedAttribute : System.Web.Http.Filters.ActionFilterAttribute
  11:     {
  12:         public override async Task OnActionExecutedAsync(HttpActionExecutedContext actContext, CancellationToken token)
  13:         {
  14:             bool supportGZip = actContext.Request.Headers.AcceptEncoding.Any(x => x.Value == "gzip");
  15:  
  16:             if (!supportGZip)
  17:             {
  18:                 await base.OnActionExecutedAsync(actContext, token);
  19:                 return;
  20:             }
  21:  
  22:             var contentStream = await actContext.Response.Content.ReadAsStreamAsync();
  23:  
  24:             actContext.Response.Content = new PushStreamContent(async (stream, content, context) =>
  25:             {
  26:                 using(contentStream)
  27:                 using (var zipStream = new GZipStream(stream, CompressionLevel.Optimal))
  28:                 {
  29:                     await contentStream.CopyToAsync(zipStream);
  30:                 }
  31:             });
  32:  
  33:             actContext.Response.Content.Headers.Remove("Content-Type");
  34:             actContext.Response.Content.Headers.Add("Content-encoding", "gzip");
  35:             actContext.Response.Content.Headers.Add("Content-Type", "application/json");
  36:         }
  37:     }
  38: }

Wednesday, January 28, 2015

Making SignalR Hub’s internal

 

Today I ran into an interesting issue. In my current project, we’re making a web application out of discrete modules. These modules should not expose their internal workings to the outside, to minimize assembly versioning issues. So we’ll ILMerge all non-public dependencies into the assembly.

One example is using SignalR. One of my modules uses signalr to notify clients. This is an internal implementation detail of my module, so it shouldn’t be exposed to the outside world.

The nice thing of this approach is, we can have multiple versions of the same assembly running in the same appdomain. So if I want another module to use a different version of signalr, there’s no issue at all.

But then I ran into a snag. SignalR requires it’s hubs to be public. But, if my hub is public, I’m exposing SignalR and I can’t ILMerge this dependency.

So how to solve this?  After a bit of digging, it’s the IHubDescriptorProvider that finds the hubs. I’ve created a provider that finds ‘only’ my hub, but it’s not difficult to see how to fetch all hubs if you want to.

   1: internal class InternalHubDescriptorProvider : IHubDescriptorProvider
   2: {
   3:    private HubDescriptor _notificationsHubDescriptor;
   4:  
   5:    public InternalHubLocator()
   6:    {
   7:        // create the descriptor that's used to find the notifications hub
   8:        _notificationsHubDescriptor = new HubDescriptor()
   9:        {
  10:            HubType = typeof(NotificationsHub),
  11:            Name = GetHubTypeName(typeof(NotificationsHub))
  12:        };
  13:    }
  14:  
  15:    private static string GetHubTypeName(Type type)
  16:    {
  17:        var lastIndexOfBacktick = type.Name.LastIndexOf('`');
  18:        if (lastIndexOfBacktick == -1)
  19:        {
  20:            return type.Name;
  21:        }
  22:        else
  23:        {
  24:            return type.Name.Substring(0, lastIndexOfBacktick);
  25:        }
  26:    }
  27:    /// <summary>
  28:    /// Retrieve all avaiable hubs.
  29:    /// </summary>
  30:    /// <returns>
  31:    /// Collection of hub descriptors.
  32:    /// </returns>
  33:    public IList<HubDescriptor> GetHubs()
  34:    {
  35:        return new []{_notificationsHubDescriptor};
  36:    }
  37:  
  38:    /// <summary>
  39:    /// Tries to retrieve hub with a given name.
  40:    /// </summary>
  41:    /// <param name="hubName">Name of the hub.</param><param name="descriptor">Retrieved descriptor object.</param>
  42:    /// <returns>
  43:    /// True, if hub has been found
  44:    /// </returns>
  45:    public bool TryGetHub(string hubName, out HubDescriptor descriptor)
  46:    {
  47:        if(string.Equals(hubName, _notificationsHubDescriptor.Name, StringComparison.CurrentCultureIgnoreCase))
  48:        {
  49:            descriptor = _notificationsHubDescriptor;
  50:            return true;
  51:        }
  52:        descriptor = default(HubDescriptor);
  53:        return false;
  54:    }
  55: }

 


One little caveat that had me pulling out my hair. On the hubdescriptor, don’t specify the ‘NameSpecified’ flag, unless you actually have the HubNameAttribute on your hub. Else it will silently eat your outbound messages.

Tuesday, January 6, 2015

In-Memory FileStream

In my current project, I wanted to ‘fake out’ the filesystem for integration tests. In several places in my code, I would first write some data to a temporary file, then later, open the file again for background processing. Now my integration tests run fine using the real filesystem, but just to make sure my tests could run in parallel, I wanted to switch to a faked filesystem.

So, my first attempt used memory streams. But then I found a crucial difference between filestreams and memorystreams. If you dispose a filestream.. the actual file is still there! Not so much with a memorystream.

So here’s an in memory filestream. If you close / dispose it.. it will still be there. Note.. it will only be cleaned up by the garbage collector. So don’t hang on to them in definetly and don’t use this in production.

   1: public class InMemoryFileStream : Stream
   2: {
   3:     private MemoryStream _memoryStream = new MemoryStream();
   4:  
   5:  
   6:     public override void Flush()
   7:     {
   8:         _memoryStream.Flush();
   9:     }
  10:  
  11:     public override long Seek(long offset, SeekOrigin origin)
  12:     {
  13:         return _memoryStream.Seek(offset, origin);
  14:     }
  15:  
  16:     public override void SetLength(long value)
  17:     {
  18:         _memoryStream.SetLength(value);
  19:     }
  20:  
  21:     public override int Read(byte[] buffer, int offset, int count)
  22:     {
  23:         return _memoryStream.Read(buffer, offset, count);
  24:     }
  25:  
  26:     public override void Write(byte[] buffer, int offset, int count)
  27:     {
  28:         _memoryStream.Write(buffer, offset, count);
  29:     }
  30:  
  31:     public override bool CanRead
  32:     {
  33:         get { return _memoryStream.CanRead; }
  34:     }
  35:  
  36:     public override bool CanSeek
  37:     {
  38:         get { return _memoryStream.CanSeek; }
  39:     }
  40:  
  41:     public override bool CanWrite
  42:     {
  43:         get { return _memoryStream.CanWrite; }
  44:     }
  45:  
  46:     public override long Length
  47:     {
  48:         get { return _memoryStream.Length; }
  49:     }
  50:  
  51:     public override long Position
  52:     {
  53:         get { return _memoryStream.Position; }
  54:         set { _memoryStream.Position = value; }
  55:     }
  56:  
  57:     protected override void Dispose(bool disposing)
  58:     {
  59:         if (disposing)
  60:         {
  61:             _memoryStream.Position = 0;
  62:             base.Dispose(disposing);
  63:         }
  64:     }
  65: }

Wednesday, December 3, 2014

Just Released: Chill 2.0

It took a bit longer than I had hoped, but I’ve just released Chill version 2.0.

What’s new:

  • New plugins available: Unity and UnityNSubstitute.
  • Cleaned up plugin discovery and selection mechanism.
  • PCL support (Many thanks to my colleague Dennis Doomen).
  • Automatic Mothers.
  • Using non-mocking containers for integration testing.
  • Many small usability tweaks.

Please: Check it out at : https://www.nuget.org/packages/Chill 

Will post more information shortly.

Wednesday, November 5, 2014

Using different containers with Chill

When Chill 1.0 wanted to know which container (for example the Chill.AutofacNSubstitute container) it needed to use, it would scan your loaded assemblies for types that implemented the IChillContainer. While this worked, it also posed several issues.

For one, you couldn’t use different types of chill containers. For example, if you wanted to have tests with several containers that do automocking, some without automocking, some with very specific registrations set up), you couldn’t do that.

The other issue had to do with portable class libraries. I wanted to make Chill a portable class library. For example if you wanted to test Xamarin IOS classes (without turning them into PCL’s), then you can only reference PCL’s or Xamarin IOS dll’s from your test project.

But, to turn Chill into a PCL, I had to change the way it did assembly scanning. PCL’s have quite a lot of restrictions with regards to assembly scanning.

However, I think the end result is quite elegant.

Basically, if you install a specific container, Chill will add an assembly level attribute, in a file called DefaultChillContainer:

// This attribute defines which container will be used by default for this assembly

[assembly: ChillContainer(typeof(AutofacNSubstituteChillContainer))]

 

This tells Chill to use this container (in this case an AutoMocking container using NSubstitute) as the default container. Now, if you want to use a different container in some situations, you can override this on a per test basis:

 

[ChillContainer(typeof(AutofacContainerWithCustomModule))]
public class When_configuring_container_with_module_and_objectmother : GivenWhenThen
{
...


Under the covers, Chill will wrap the container you specify in a AutoMotherDecorator (more on AutoMothers in a later blog post). If you don’t want this, then you can specify a custom ChillContainerInitializer:


[ChillContainerInitializer(typeof(DefaultChillContainerInitializer<AutofacContainerWithCustomModule>))]

 

The DefaultChillContainerInitializer is the class that wraps the ChillContainer the AutoMotherDecorator, so you can implement your own class if you don’t like this behavior. Now I don’t expect that this happens often, but it’s nice to have the option.

As always, keep it cool, keep it Chill!

Integration testing with Chill

 

Unit testing means testing software components in isolation. This can be a powerful technique to validate some complex pieces of logic.

However, if you follow the Single Responsibility Principle, you’ll find that many of your components hardly contain enough logic to warrant unit testing. For example, a webapi controller might just take a message object, validate it using a validator component, map it to an internal data format, and then hand it off to yet another component for validation. All it does is chain some components together. If you dogmatically try to unit test each of these components in isolation, you’ll end up with a system that becomes difficult to architecturally.

In those cases, integration tests make much more sense. You want to make sure that the entire collection of components work well together, not that each individual piece does what it needs to do.

Note, unit tests do make a lot of sense for some (sufficiently complex) components. As always, it’s important to know what technique to apply when.

Integration testing does have it’s own set of challenges. Ideally, you’d like to start with a pristine environment, prepare a certain ‘start situation’, then execute a test and validate the result. In the next couple of weeks, I’ll put out a sample application that demonstrates some of these capabilities.

But for now, I can demonstrate how you can setup a container in exactly the same way that you’d do in your application.

Suppose you have several registrations you’d like to make in your container. Here, I’m doing that in Autofac in a module:

   1:  
   2: public class CustomAutofacModule : Module
   3: {
   4:     protected override void Load(ContainerBuilder builder)
   5:     {
   6:         builder.RegisterType<TestService>().As<ITestService>();
   7:         builder.RegisterType<TestSingleton>().SingleInstance();
   8:         base.Load(builder);
   9:     }
  10: }

Ok, great.. now how would you set up a chill container that uses this? The easiest way is to create a custom container, that derives from  AutofacChilContainer. 



   1: /// <summary>
   2: /// You can define 'non mocking' with all the type registrations that you would otherwise in your application. 
   3: /// This can either be done in the App. This class also creates a single 'parent' container and then child containers
   4: /// per test. 
   5: /// </summary>
   6: internal class AutofacContainerWithCustomModule : AutofacChillContainer
   7: {
   8:     private static ILifetimeScope staticContainer;
   9:     private static object syncRoot = new object();
  10:     public AutofacContainerWithCustomModule()
  11:         : base(CreateContainer())
  12:     {
  13:  
  14:     }
  15:     /// <summary>
  16:     /// This method creates the Autofac container and registers the custom type 
  17:     /// </summary>
  18:     /// <returns></returns>
  19:     private static ILifetimeScope CreateContainer()
  20:     {
  21:         if (staticContainer == null)
  22:         {
  23:             lock (syncRoot)
  24:             {
  25:                 if (staticContainer == null)
  26:                 {
  27:                     var builder = new ContainerBuilder();
  28:                     builder.RegisterModule<CustomAutofacModule>();
  29:                     staticContainer = builder.Build();
  30:                 }
  31:             }
  32:         }
  33:         return staticContainer.BeginLifetimeScope();
  34:     }
  35: }

This way, Chill will setup your Autofac registrations once. Very welcome if you’re registering expensive things such as NHibernate SessionFactories. It will also setup up two lifetime scopes. One per test run (since it’s a static singleton) and one child scope per test. This child scope can be customized to your hearts content.


Now if you wish to use this container, you can set the following attribute on class or assembly level:


[ChillContainer(typeof(AutofacContainerWithCustomModule))]