Wednesday, 28 January 2015

Xamarin Forms contacts search

I’m in the middle of writing a Xamarin Forms app and today I needed to add in a contacts search page, and remembered that James Montemagno had created a plugin that exposes contacts in a platform neutral manner so I downloaded it and used it in my app.

I also wanted to add a search bar, and again there’s a control in XF for that, so I ended up with (somewhat simplified) the following XAML…

  
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<SearchBar x:Name="search" Placeholder="Search">
</SearchBar>
<ListView Grid.Row="1" ItemsSource="{Binding FilteredContacts}"
IsGroupingEnabled="true" GroupDisplayBinding="{Binding Key}"
GroupShortNameBinding="{Binding Key}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" TextColor="Black"
Detail="{Binding PhoneNumber}" DetailColor="Gray">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>

I have removed some of the XAML as it’s not that important to this post (it’s available in the download). Now, with that in place (and a load of code in the view model which I’ll get to in a minute) I got a UI as follows…


iOS Simulator Screen Shot 28 Jan 2015 22.32.19


So far so good. Then I needed to hook up the search box, and as I’m using XAML (and if you’re not, you should give it a try as it’s way easier to create UI’s using it) I needed a way to bind to the search box to that I could respond to the TextChanged event.


Another excellent package that you’ll want to use it the Xamarin.Behaviors package by Corrado – massive thanks to him for putting this together, it’s excellent!


Behaviors to the rescue


By adding a behavior into the XAML, I can handle an event – so in this case I added the following to the SearchBar…

  <SearchBar x:Name="search" Placeholder="Search">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<b:EventToCommand EventName="TextChanged"
Command="{Binding SearchTextChanged}"
CommandParameter="{Binding Text, Source={x:Reference search}}"/>
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</SearchBar>

This hooks the TextChanged event of the search bar, calls the SearchTextChangedCommand on my view model, and passes through the value of the Text property of the search bar. Yay!.


Or not.


The problem I found was that my command was being passed a string, but it was the text before the ne character was entered, so say I pressed ‘X’ in an empty search bar, my code would be called with an empty string. Pressing ‘A’ next, my command would get ‘X’, and pressing ‘M” next, my code would get ‘XA’. I was always getting the data just prior to the new character – so I guess that the TextChanged event should be more clearly termed as the TextChanging event.


Anyway, I needed to fix this – so looked at the actual event and it contains two properties, the current text and the new value. All I needed to do was get the new vale of the event arguments and I’d be away.


To the best of my knowledge there is no way to bind to the event arguments, you need to write some additional code (this was true in WPF and Silverlight, I’ve done exactly the same there too). So, I cranked out a new behavior that attaches to the SearchBar’s TextChanged event, and calls the command with the new value of the text property. My XAML is therefore this…

  <SearchBar x:Name="search" Placeholder="Search">
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<bh:SearchBarTextChanged Command="{Binding SearchTextChanged}"/>
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</SearchBar>

Here I'm using my SearchBarTextChanged behavior to hook to the SearchTextChanged command, and sure enough now when I type in the search bar I get the desired effect. Excellent!


Filtering in code


In the view model I use James’ contacts plugin to select all contacts that have a mobile phone, and that have at least a forename or surname (my real code blew up on a colleagues iPhone as he has a contact with just a company name). I tuck this list away as the source, and then create a filtered collection from the source and the filter statement.

CrossContacts.Current.PreferContactAggregation = false;
var hasPermission = CrossContacts.Current.RequestPermission().Result;

if (hasPermission)
{
// First off convert all contacts into ContactViewModels...
var vms = CrossContacts.Current.Contacts.Where(c => Matches(c))
.Select(c => new ContactViewModel(c));

// And then setup the contact list
var grouped = from contact in vms
orderby contact.Surname
group contact by contact.SortByCharacter into contactGroup
select new Grouping (contactGroup.Key, contactGroup);

foreach (var g in grouped)
{
_contacts.Add (g);
_filteredContacts.Add (g);
}
}

The above code uses some Linq to select all contacts and group them by first character of their surname. I created a simple Matches(contact) function that checks that the contact has a mobile phone number and also that they have one of forename or surname.


Then I have the code that is called to filter the collection when you type text into the search bar...

private void FilterContacts(string filter)
{
_filteredContacts.Clear ();

if (string.IsNullOrEmpty(filter))
{
foreach (var g in this.Contacts)
_filteredContacts.Add (g);
}
else
{
// Need to do some filtering
foreach (var g in this.Contacts)
{
var matches = g.Where (vm => vm.Name.Contains (filter));

if (matches.Any())
{
_filteredContacts.Add (new Grouping (g.Key, matches));
}
}
}
}

This is a bit ropey but does the trick. As the collection is an ObservableCollection, any changes are shown in the UI immediately.


Code


I’ve created a simple example project (the one shown above) that you can download. Hopefully this will help someone out. I’ve not tried this on Android or Windows Phone as yet, but as none of the code is in the platform specific library I can’t see any reason for it not to work on those platforms too.


Bye for now!

Friday, 23 January 2015

Xamarin Forms Navigation–Dealing with Login

This is the third in a series of posts on Xamarin Forms – in this instalment I want to add login capability to my app, but this isn’t as simple as I thought it would be. I’m used to crafting interfaces with XAML in WPF and Silverlight, and have been doing so for several years now, but with Xamarin Forms things are a little different.

Here’s what I want to be able to do, courtesy of Visio…

image

When the app starts up I’ll check if the user has a valid token, and if so skip the login part and go straight to the main page.

If however the user hasn’t yet logged in I want to show a “carousel” where I can do some app advertising, then let them choose from one of the login providers I’ve integrated, and once logged in show the main form. The gnarly part here is the navigation support – once at the MainForm stage I don’t want to allow the user to “back out” into the login part, and so far on the intertubes I’ve not seen a clear way of doing this so looked into this myself.

I’m using Xamarin Forms 1.3 which has improved navigation support, so the first thing I tried was a main form that cleared out the navigation stack when it showed up. This worked to a fashion, in that the back-stack was cleared, but it left a “< Back” button on the navigation section when I arrived at the main form, and that was less than ideal.

After trying some other options (non of which panned out) I went back to first principles and looked at how the application startup sequence worked, and from that arrived at a simple solution – at the point where I need to display the main page, I simply call the following…

    var nav = new NavigationPage(new MainPage());
nav.BarBackgroundColor = Color.FromHex("#195174");
nav.BarTextColor = Color.White;

Application.Current.MainPage = nav;

And boom - the main page is shown and there's no previous pages that can be navigated to.

I’d originally created my main page and set that as the root, then coded the login forms as modal, and whilst that worked OK it had the undesired behaviour of showing the main form first (briefly), then navigating to the login page. That wasn’t particularly great as I want login to be the first thing seen when the application is run for the first time.

The downside of my approach here is that there’s no transition between the last login page and the main form, I haven’t found a way to do that at the moment.

I’m not sure if this is the best method either – however there doesn’t seem to be (or I cannot find) any alternatives that work quite how I want them to. I want to be able to use navigation during login, as I have a carousel page and then a provider selection page (and maybe more pages after that, once I’ve written them!), so using a Modal login page doesn’t suit my purposes.


Demo Code


If you would like to grab my example project please download it here. The structure is deliberately simple (I usually use Autofac and XAML in my projects, this has neither as there’s less to setup). When you run the app you’re on the carousel view which consists of three pages…


IMG_1304    IMG_1305    IMG_1306


I’m using a carousel here and a timer to move between the images, you can swipe too should you wish to. When you click on the “Providers” button a new page is shown, where you would ask the user to choose their login provider. I’ve cheated and just shown a login button…


IMG_1307


When the Login button is clicked I construct a new navigation page and the main page within it, and then set the application root page to this combination using the code shown above which gives the main page shown below.


IMG_1308




You can navigate elsewhere using the button…


IMG_1309  IMG_1310


And you can navigate directly back to the root page when you’re on the “At the end” page.


Conclusion


In this example I’ve attempted to show how you can “break out” of the navigation hierarchy and start a new navigation stack. There may be a better way to do this and if so please let me know!

Tuesday, 20 January 2015

Self hosting workflow–working with InstanceStore and InstanceOwner

I’ve not been doing a great deal of Workflow recently but had to fix an issue at a customer today and as there’s such poor information about this on the Web I put fingers to keys to blog about it.

If you are self-hosting workflows using WorkflowApplication you’ll typically have some code such as the following to setup the workflow instance store…

    instanceStore = new SqlWorkflowInstanceStore
(@"Data Source=.\SQLEXPRESS;Initial Catalog=SampleInstanceStore;
Integrated Security=True;Asynchronous Processing=True");

InstanceHandle handle = instanceStore.CreateInstanceHandle();
InstanceView view = instanceStore.Execute(handle,
new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
handle.Free();

instanceStore.DefaultInstanceOwner = view.InstanceOwner;

The question is - where does this go? I’ll get on to that in a moment.


When you want to run a workflow you need to set it’s instance store – so you’ll typically do this…

    WorkflowApplication application = new WorkflowApplication(activity);
application.InstanceStore = instanceStore;

And then somewhere online you might have seen the DeleteWorkflowOwnerCommand as that’s the opposite of the CreateWorkflowOwnerCommand so has to be called somewhere, doesn’t it?


If all of this has you confused this is the article that will help you.


Instance Store: One Per Process


When creating the instance store you need no more than one per process. You can run multiple workflow instances in this process, and each will play nicely together – but all will use the same store. You don’t need loads, one will do per process.


I’m using AutoFac so have setup a dependency to be SingleInstance(), and each workflow wrapper that I run imports that single instance. The wrapper is shown below…

    public interface IWorkflowInstanceStore
{
InstanceStore Store { get; }
}

The implementation is also pretty trivial...

    public class WorkflowInstanceStore : IWorkflowInstanceStore, IDisposable
{
public WorkflowInstanceStore(string connectionString)
{
_instanceStore = new SqlWorkflowInstanceStore(connectionString);

InstanceHandle handle = _instanceStore.CreateInstanceHandle();
InstanceView view = _instanceStore.Execute(handle,
new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
handle.Free();

_instanceStore.DefaultInstanceOwner = view.InstanceOwner;
}

public InstanceStore Store
{
get { return _instanceStore; }
}

public void Dispose()
{
if (null != _instanceStore)
{
var deleteOwner = new DeleteWorkflowOwnerCommand();
InstanceHandle handle = _instanceStore.CreateInstanceHandle();
_instanceStore.Execute(handle, deleteOwner, TimeSpan.FromSeconds(10));
handle.Free();
}
}

private InstanceStore _instanceStore;
}

As you'll see here this is a disposable class and in the Dispose() method I call the DeleteWorkflowOwnerCommand. When running workflows, you'll get a row in the LockOwners for each instance store, and these are tidied up by the RecoverInstanceLocks stored procedure which runs periodically. This can be a source of poor performance, as if you use an instance store per workflow application (which is very common given the lack of guidance on this matter), then you'll end up with a large number of rows in this table and RecoverInstanceLocks will show up on your SQL traces as taking a long time to execute. The culprit isn't directly the stored procedure, it's the use of too many rows in the LockOwnersTable. Typically there should be just one row in there per process that runs workflows.


Workflow Runner: One per workflow application


Next up you’ll need a class that runs workflows – typically you’ll write a simple wrapper such as the one I’ve done below, this wraps running workflows and resuming bookmarks with Task based operations so that you can easily integrate Workflow into your code. Note – you might want to process other events and probably do some logging inside this class too, I’ve just provided a minimal implementation…

    public class WorkflowHoster
{
public WorkflowHoster(IWorkflowInstanceStore instanceStore,
params object[] services)
{
_instanceStore = instanceStore.Store;
_services = services.ToList();
}

public Task RunInstance(Activity root)
{
WorkflowApplication application = new WorkflowApplication(root);
foreach (var service in _services)
application.Extensions.Add(service);
var tcs = new TaskCompletionSource();

application.InstanceStore = _instanceStore;

application.PersistableIdle = (e) => PersistableIdleAction.Unload;
application.Unloaded = (e) => tcs.SetResult(e.InstanceId);
application.Aborted = (e) => tcs.SetException(e.Reason);
application.Run();

return tcs.Task;
}

public Task ResumeInstance(Activity root, Guid workflowInstanceId,
string bookmarkName, object bookmarkData = null)
{
WorkflowApplication application = new WorkflowApplication(root);
application.InstanceStore = _instanceStore;
var tcs = new TaskCompletionSource();

application.PersistableIdle = (e) => PersistableIdleAction.Unload;
application.Unloaded = (e) => tcs.SetResult(DateTime.UtcNow);
application.Aborted = (e) => tcs.SetException(e.Reason);
application.Load(workflowInstanceId);
application.ResumeBookmark(bookmarkName, bookmarkData);

return tcs.Task;
}

private InstanceStore _instanceStore;
private AutoResetEvent _instanceUnloaded = new AutoResetEvent(false);
private List<object> _services;
}

You may also want to pass parameters to the workflow instance etc. - as I mentioned the above is a minimal implementation just to show how this works.


Running a workflow


With that stuff defined you can run a workflow as follows…

    var store = GetThePerProcessStoreFromSomewhere();

var host = new WorkflowHoster(store);
Task wf = host.RunInstance(rootActivity);
// Now wait for the wf task to complete...

The task will complete when the workflow unloads (which obviously happens if the workflow completes entirely, or if it goes idle and persists due to a bookmark or delay).


Wrap Up


If you want to self-host workflow, then using your own persistence store requires a bit of knowledge which is hard to come by on the intertubes.


Create a single instance-store per process, and only call DeleteWorkflowOwnerCommand once when your process is shutting down. That should be all you need.

Sunday, 18 January 2015

Xamarin Forms–Using background images on iOS

Following on from my last post on creating A Light status bar for iOS, I wanted to go one step further and add in a full-screen background image to my application. This is very easy without a navigation bar, but with one it’s a bit more involved so I thought a blog post would be in order.

If you have no navigation bar then all you really need to do is create an image of the right size (for each physical phone you want to support, such as 4S, 5S, 6, 6 Plus), add images to the resources directory and use them in code or XAML. With a navigation bar it’s a bit more involved as you need to split your source image into two separate images (one for the navigation bar and one for the remainder of the screen).

Then when you have the images defined you need to hook the images to the correct controls, and this is where it gets a little more complex. With a NavigationPage we need to set the navigation bar’s background to an image – but we can’t do this in regular Xamarin Forms code as the property is only available in a custom renderer, so we’ll need to create one.

First off though we need an image – I chose one I took in 2006 whilst on holiday with my family – this is the last time we were all together and it was a beautiful day. Anyhow, I extracted four images in total as shown in the following…

Original Marked Up

The red outline contains the navigation bar image (640px * 128px) and the background image (640px * 1008px) – these are both for an iPhone 5S which is what I have to develop on at the moment.

The green outline contains the two images for the landscape view, the navigation bar being 1136px * 64px, and the background image being 1136px * 576px. The navigation bar is shorter by default in landscape mode as the status bar is switched off. I believe it’s possible to override this and display the status bar, but I don’t need that so haven’t looked into it further.

I named those images as follows…

  • PortraitNavBar@2x.png
  • PortraitBackgrouns@2x.png
  • LandscapeNavBar@2x.png
  • LandscapeBackground@2x.png

With that done I then needed to write a bit of code. First up I had to ensure that the correct background image was shown for the content page – this was simply a job of overriding the OnSizeAllocated member of my content page…

    protected override void OnSizeAllocated (double width, double height)
{
base.OnSizeAllocated (width, height);

if (width < height)
this.BackgroundImage = "PortraitBackground.png";
else
this.BackgroundImage = "LandscapeBackground.png";

}

The OnSizeAllocated method is called when the size changes on the phone and it provides the size of the page, so this seemed like a reasonable place to determine which image to load up.


Then I needed to add in a custom render so added a deriver navigation page as shown below…

    public class CustomNavigationPage : NavigationPage
{
public CustomNavigationPage (Page content) : base(content)
{
}
}

With that defined I could then add the renderer. The purpose of this renderer is to render the background image of the navigation bar...

[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(XamFormsTestbed.iOS.Renderers.CustomNavigationPageRenderer))]

namespace XamFormsTestbed.iOS.Renderers
{
public class CustomNavigationPageRenderer : NavigationRenderer
{
public override void ViewDidLoad ()
{
base.ViewDidLoad ();

var img = UIImage.FromBundle ("PortraitNavBar.png");
this.NavigationBar.SetBackgroundImage (img, UIBarMetrics.Default);

img = UIImage.FromBundle ("LandscapeNavBar.png");
this.NavigationBar.SetBackgroundImage (img, UIBarMetrics.Compact);
}
}
}

Originally I'd tried responding to size changes here, but then read an article that discussed the above mechanism and it appeared to work.


With all that in place I can now display a background image in the navigation bar and also have a correctly formatted image for both landscape and portrait orientations...

IMG_1302

IMG_1303


And there you have it – a full background image with a navigation bar. Hopefully this will help someone with their application.

Saturday, 17 January 2015

Xamarin Forms – A light status bar for iOS

I’m writing an app in Xamarin Forms at the moment and as part of that I want to have a light on dark theme rather than the dark on light default. Ultimately there will be a background image on the pages that extends into the navigation area at the top of the screen, but for now a coloured backgound will do. This post will show how to accomplish this.

I started with a simple Xamarin Forms app and set the BackgroundColor of the content page to Green, here’s what I got…

Screen Shot 2015-01-17 at 10.26.28

That status bar isn’t much good is it? To alter it you need to do two things…

  • Alter the info.plist file and set the Status Bar Style to LightContent
  • Add an additional item to the .plist file

Open info.plist and scroll down to the following section…

Screen Shot 2015-01-17 at 10.27.07

You may or may not want a status bar whilst the app is starting up – if not then check “Hide during application launch”.

Next, at the bottom of the plist editor there’s three tabs, click on Source and then add in the following…

Screen Shot 2015-01-17 at 10.27.42When you click “Add New Entry” you can then select “View controller-based status bar appearance” from the dropdown, then click/tab off it and it’ll change the type column to Boolean. The default is Yes, you need to set it to No.

With that done, rebuild your app and run it and voila, you get this…

Screen Shot 2015-01-17 at 10.28.18

Looking good! But that’s not the end of the story – what happens when you add a navigation bar to the app? Ah, well – you get this…

Screen Shot 2015-01-17 at 10.29.52

That’s with the following code in my App.cs file…

public class App
{
    public static Page GetMainPage ()
    {   
        var mainPage = new MainPage ();
        var navPage = new NavigationPage (mainPage);
        navPage.BarBackgroundColor = Color.Green;
        return navPage;
    }
}

And if I happen to set a title on my content page it shows as follows…

Screen Shot 2015-01-17 at 10.57.05

Now at this point in my travels around the intertubes I found a bunch of articles that stated I should override some method of the view and explicitly state that I wanted a light status bar. I spent a load of time on this but all to no avail, so I went back to the original code and had a poke around and what did I find but the BarTextColor property. Setting that had the desired effect…

Screen Shot 2015-01-17 at 10.57.44

The code is now as follows…

public class App
{
    public static Page GetMainPage ()
    {   
        var mainPage = new MainPage ();
        var navPage = new NavigationPage (mainPage);
        navPage.BarBackgroundColor = Color.Green;
        navPage.BarTextColor = Color.White;
        return navPage;
    }
}

I hope that helps someone as there seems to be a lot of misinformation on the intertubes about how to get this to work. I’m on the latest Xamarin Forms build, as of today that’s 1.3.1.6296.

Thursday, 18 December 2014

Getting NServiceBus, SignalR and Autofac to work together

I’m currently working on an existing web app that we’re updating to add in NServiceBus and SignalR. A broad brush overview is shown below…

image

Here a request is sent from the browser which goes to a SignalR hub inside the website. That request is then sent onto the bus and some back end magic happens, which ultimately ends up in a response being sent to the bus. This is picked up by the website and a response is pushed down to the client courtesy of SignalR.

If we look into what’s happening inside the website we see the following…

image

The hub implements an interface that’s injected into the message handler, so that the handler can call back to the hub when the response message comes in, which ultimately then makes the hub call back to the browser to finish the loop.

Getting all this setup was a bit of a bother and I went down a few blind alleys before getting it all to work properly, hence documenting it so that I can hopefully short-circuit someone else’s work.

In pseudocode this is what happens…

  • The browser makes a request to the hub.
  • The hub code creates a unique Request Id, and stuffs this into a dictionary, mapping this Request Id to the SignalR Context.ConnectionId.
  • The hub then sends a message onto the bus, this contains the Request Id.
  • After the back-end has processed this message a response is placed on the bus, again containing the Request Id.
  • The message handler receives the message and uses the callback interface and Request Id to build a dynamic object that we can call the browser back with.
  • The message handler then makes the callback.

For this example I’m doing the callback within the message handler, but you could encapsulate this fully within the Hub too if you prefer. OK, enough explanation, on to some code…

    public interface ICallback
{
dynamic GetCallback(Guid requestId);
}



This interface is used to communicate between the message handler and the Hub. In addition I added a “registration” service that is used to map a Request Id to a client connection Id…

    public interface IRegistration
{
void Register(Guid id, string data);

string GetRegistration(Guid id);
}



The implementation of this service was a simple dictionary, this however should be beefed up as it needs a “tidy up” mechanism that will ensure that data is removed from this dictionary when the client disappears. The hub then is as shown below…

    public class WibbleHub : Hub, ICallback
{
public WibbleHub(IBus bus, IRegistration registration)
{
_bus = bus;
_reg = registration;
}

public void RequestWibble(string text)
{
Guid requestId = Guid.NewGuid();

_reg.Register(requestId, Context.ConnectionId);

_bus.Send(new WibbleMessage { RequestId = requestId, Text = text});
}

public dynamic GetCallback(Guid requestId)
{
dynamic callback = null;
string clientId = _reg.GetRegistration(requestId);

if (null != clientId)
callback = Clients.Client(clientId);

return callback;
}

private IBus _bus;
private IRegistration _reg;
}



The hub imports the bus and registration services, and the RequestWibble method is the one we’re calling from the web client. This registers the mapping between the Request Id and the client Connection Id, and then sends a message onto the bus.


The GetCallback method uses the registration service to find the client connection Id, then returns a dynamic object hooked to that client if the Id matches one that has been registered.


The message handler is fairly simple too…

    public class WibbleHandler : IHandleMessages<WibbleMessage>
{
public WibbleHandler(ICallback callback)
{
_callback = callback;
}

public void Handle(WibbleMessage message)
{
var cb = _callback.GetCallback(message.RequestId);

if (null != cb)
{
try
{
cb.wibbleSucceeded(message.Text);
}
catch (Exception ex)
{
int i = 0;
}
}
}

private ICallback _callback;
}



The handler imports the ICallback interface (exposed by the Hub), and when it handles the incoming message it calls the GetCallback() method to retrieve the dynamic object that allows us to call down to the web client.


The last piece of the puzzle is wiring this up, and that was the main thing that took time to get right, mainly down to my misunderstanding of how NServiceBus does its stuff. I created a DependenciesConfig file as follows…

    public static class DependencyConfig
{
public static void BuildDependencies()
{
var container = BuildContainer();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}

public static IContainer BuildContainer()
{
if (null == _container)
{
var builder = new ContainerBuilder();

builder.RegisterControllers(Assembly.GetExecutingAssembly())
.PropertiesAutowired();

builder.RegisterType<WibbleHub>()
.AsSelf()
.As<ICallback>()
.ExternallyOwned()
.SingleInstance();

builder.RegisterType<Registration>().As<IRegistration>().SingleInstance();

_container = builder.Build();

var config = new BusConfiguration();
config.UsePersistence<InMemoryPersistence>();
config.UseTransport<RabbitMQTransport>();
config.UseContainer<AutofacBuilder>(c => c.ExistingLifetimeScope(_container));

var bus = Bus.Create(config);
bus.Start();

}

return _container;
}

private static IContainer _container;
}



This has a static BuildContainer method that creates the AutoFac container, and there are a couple of things of note. First off is the registration of the hub, this is registered as a singleton, as is the registration service too.


Then (and this is the bit that I got wrong) is the configuration of the bus. First off, the container is built before the bus is constructed, so the bus itself is not constructed as part of the container itself, it lives “outside”. The bus is setup to hook to the Autofac container using the UseContainer() member, this links the bus to the registered components, and means that when a message comes in on the bus that it can resolve all dependencies such as the ICallback interface exposed by the hub.


Now to the voodoo magic. In the above there is nowhere that the bus itself is registered with the Autofac container, so conventional wisdom would dictate that any components requiring IBus wouldn’t be able to resolve it, so for example this controller shouldn’t work…

    public class DefaultController : Controller
{
public DefaultController(IBus bus)
{
_bus = bus;
}

public ActionResult Index()
{
return View();
}

private IBus _bus;
}



But it does work. How is a mystery. After a bit of searching I came across this post on Stack Overflow that indicates that NSB does this for you. That’s great, but also somewhat confusing for anyone who doesn’t know this beforehand, which presumably is everyone who uses NSB and Autofac, or any IOC container probably as people are used to registering dependencies themselves, rather than some magic happening. Personally I’m not a fan of this magic, it’ll most likely trip you up. However, with this in place it all works as expected – I can then pop some Javascript into my client and everything works as expected.


There’s one more class to add and that’s the startup for Owin, so that we can get SignalR up and running properly…

    public class Startup
{
public void Configuration(IAppBuilder app)
{
var container = DependencyConfig.BuildContainer();

GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);
app.UseAutofacMiddleware(container);
app.MapSignalR(new HubConfiguration { EnableDetailedErrors = true });
}
}



The demo (attached) has a simple form where you can enter text, click a button and lo and behold a message is displayed on screen. That’s pretty useless, but at least is shows how NServiceBus, Autofac and SIgnalR can play nicely together. I’m using RabbitMQ as my messaging infrastructure, feel free to bring your own along if you would prefer.


Hope this helps someone!

Monday, 17 November 2014

Fun (or rather not) with EventSource

I’ve been an advocate of good logging in applications (especially server side ones) for many years, and today I’m working on something for myself and wanted to use the latest and greatest event logging framework so chose System.Diagnostics.Tracing (which has been around since .NET 4 days). I’ve used it before but today I came across an issue that had me stumped for some time.

I’d created a custom event source, and derived this from an interface so that I could inject an implementation in at runtime…

  public interface ILogger
{
void T1(string message);
void T2(string message);
}

public class Logger : EventSource, ILogger
{
public void T1(string message) { this.WriteEvent(1, message); }
public void T2(string message) { this.WriteEvent(2, message); }
}

But when I used PerfView to view my events there were none. After a lot of head scratching I tried a sample from Vance’s blog (which seems to be the main place to get any information about this feature) and of course that worked first time. I did some more fiddling in code and then stumbled across the reason as I was debugging the code. It’s worthy of a blog post, as this may well catch someone else out.


I’d created the interface and implemented it in the EventSource derived class so that I could mock out the logger code for testing – however this was the part that caught me out. When the code runs, the EventSource class builds a manifest that contains details of the "events" that are written out – and this uses the following bit of reflection to get all the methods that we want to expose as "events" in the ETW trace…

  MethodInfo[] methods = eventSourceType.GetMethods(BindingFlags.NonPublic | 
BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.DeclaredOnly);

I’ve highlighted the offending enum value above. This is saying "find me all methods whether public or not, defined on this Instance ONLY". So, because I’d created an interface and then implemented that interface, my methods were not found by the code that generates the manifest, and hence I wasn’t getting anything useful in the ETL file.


The net effect of this is that I cannot directly use an interface to define an interface for the events I want to emit. There are a few ways around this I can think up…



  • Hard-code the logger class as in the examples on Vance’s posts. Nope, not going to fly, I this stuff to be mockable/testable!
  • Create an EventSource derived class and add shim methods to call the actual logging methods
  • Write my own version of EventSource, seems like a lot of work for little gain!
  • Create a shim class that forwards all calls to the EventSource derived class

Of these I picked the last, as I do want my event source code to be mockable, and it seemed to be the least bad of the options, so I ended up with the following class...

  public class ActualLogger : EventSource
{
public void T1(string message) { this.WriteEvent(1, message); }
public void T2(string message) { this.WriteEvent(2, message); }
public static ActualLogger Instance { get { return _instance; } }
static ActualLogger _instance = new ActualLogger();
}

public class Logger : ILogger
{
public void T1(string message) { ActualLogger.Instance.T1(message); }
public void T2(string message) { ActualLogger.Instance.T2(message); }
}

Well, something like that anyway!


As an aside, if you want to look at the manifest that is generated from your EventSource derived class, there's a static method on EventSource that can be useful...

    var manifest = EventSource.GenerateManifest(typeof(ActualLogger), typeof(ActualLogger).Assembly.Location);

Hope this helps someone!