When building WP7 applications there may be times where you want to trap the Back Button action in order to perform your own custom action. For example if you are editing some values and a user has not saved the data and presses the back button you may want to perform some action to validate the data. Or you may want to update some state about your application. The good news is that catching the back button action in WP7 is extremely easy.
In order to do this all you need to do is override the OnBackKeyPress method on your PhoneApplicationPage. When you override this you will have access to CancelEventArgs object which provides you access to the Cancel action. If you truly want to stop the user from navigating way from that page (please keep in mind that this type of action needs to be used very sparingly) all you need to do is set the e.Cancel = true and the navigation will stop.
Sample method
protected override void OnBackKeyPress( System.ComponentModel.CancelEventArgs e ) { e.Cancel = true; }
Please keep in mind that when stopping the back action on the phone you are breaking the standard user experience and this should be done ONLY when needed.
Till next time,
Mark and Clark over at developersmackdown.com just published ‘my’ show: http://developersmackdown.com/archives/SingleShow/30. We spent time talking about REST and SOAP as well as a number of other topics related to REST. One of the things that I don’t think was made clear enough was that REST and SOAP are not competing service techniques. Each technology/interface type has an appropriate use case. When integrating applications within an enterprise, the development team needs to worry about:
- Security
- Transactions
- Reliable delivery of messages
- Integration with tooling for other developers
In the enterprise case, WCF + SOAP/WS-* can make integration between systems pretty simple. Yes, the teams may struggle with getting the security setup just right between domains, but overall, things will go well, especially if the setup requires communicating between different WS-* implementations. Finally, enterprise integrations typically happen for applications running on the same network/VPN. The infrastructure for an enterprise is different than that for the web. It’s important to build your applications for their environment.
When integrating applications over the Internet, sometimes WS-* adds too much complexity. For extensive integration across partners who are connected via the Internet, there is some benefit to understanding REST. REST will allow your application to scale using the HTTP architecture. Features such as caching, proxy servers, and the general uniform interface exposed by HTTP helps make things work better on the global network.
Because of my point of view here, when asked “do you prefer SOAP or REST?”, I am forced to answer “For what scenario?” I’m not popular in either circle, but understanding both helps me get stuff done.
One of the built in UI elements for WP7 is the Application Bar. This is a bar that allows you to put buttons or menu items on in order to allow your user to interact with your application. The major downside to the Application Bar is that it is not a ‘native’ XAML control. This means it is not bindable and is not skinable w/ templates. Which by the way SUCKS (I hope this changes at some point in the future).
However you are still able to change the Background and Foreground colors in order to spice up application.
Adding a value for Background and Foreground could not be simpler. All you need to do is the following:
<phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" Opacity="0.75" ForegroundColor="#FF9D386E" BackgroundColor="#FF8B8888" > <shell:ApplicationBarIconButton x:Name="appbar_button1" IconUri="/Images/appbar_button1.png" Text="Button 1"></shell:ApplicationBarIconButton> <shell:ApplicationBarIconButton x:Name="appbar_button2" IconUri="/Images/appbar_button2.png" Text="Button 2"></shell:ApplicationBarIconButton> <shell:ApplicationBar.MenuItems> // menu go here </shell:ApplicationBar.MenuItems> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>
In the XAML above I have bolded three attributes of the ApplicationBar. Opacity, Foreground and Background. All you need to do is provide your colors (or opacity) to these attributes and your app bar will have a new style set to it.
One thing is I was NOT able to get a gradient to work in ANY capacity which sucks, but hopefully it will come in a future release.
Consistency: We developers love it don’t we?
We come up with beautiful architectures making sure everything is consistent. If we use a service in one place, we’ll use it everywhere. If we have a ViewModel for showing data, we’ll use a ViewModel everywhere, even if it’s not needed. Because we need to be consistent.
Partly I guess this is motivated because we think that being consistent helps ourselves and teammates understand what’s going on, even if that drives us to YAGNI and a series of WTF’s of why we did something that’s not required. We do it to be consistent!
It might seem inoffensive, but consistency can be damaging. It leads us into trying to homogenize everything despite it not being the appropriate approach in many cases.
So next time someone asks:
…one of the reasons, most likely, is because we like to be consistent!
Breaking consistency when required not only lowers levels of WTF’s, it can even help scalability
When you encounter a bug, do you first write a failing test before fixing it? You should. But the vast majority of us sometimes do not. External pressure (read Customer, Teammates or Management) moves us in the opposite direction. Everything we’ve learnt about unit testing and good software practices go out the window, and the sheer pressure forces us to fix the issue as fast as possible! We focus more on getting the job done* and deploying than worrying about adding another test to our suite.
Adding that test is not about increasing our code coverage or patting ourselves on the back, with an optional tweet, that we are good developers. It’s about putting regression tests in place.
Of course, we could always just apply the fix, and then later, calmly add a test. However, there’s always another urgent bug fix, feature, or customer breathing down our necks, so things just get putt off.
It’s hard to not be tempted to just fix something then and there. Fight the temptation though if you can. Write that failing test first!
[*Implicitly changing the definition of Done on the go]
If you have seen any of the demos for the Windows Phone 7 you may have seen or heard about the concept of its Toast Notification. A Toast Notification is a way for the device to receive a message which originates from some webservice and can be used to display useful information to a user. When the user receives a toast they are presented with a fairly unobtrusive dialog which displays the message. (see below)
As great as it is to be able to send a toast and have your user get the information there is one major flaw in my opinion. This flaw is that there is no way for 3rd party developers (that would be everyone outside of Microsoft and their OEMs) to trigger this notification from the device itself. Because this toast notification is so elegant and unobtrusive I can easily think up scenarios where a developer may want to trigger this notification within their application to tell a user about something. However w/ v1 of the WP7 tools developers will NOT be able to trigger this without sending an request to the notification services (aka doing a full round trip to a web service and back). This sucks, but this logic can be duplicated w/ very little effort.
How to create your own popup notification.
Creating the UserControl which will contain the main content for the notification. When using the Popup control (from System.Windows.Controls.Primitives) you need to set the .Child property to some sort of UI element for display. The simplest thing to do is to create a new user control which will hold your layout for your notification window. Below is an example of my (very simple) control.
Setting up your View to Create the Notification
Inside your view where you want to display this popup you will need to create and use the Popup control. Using this is pretty easy. Below is the code which can be used to create and display this popup. Please keep in mind that for this post there is no 10 second timer which closes the popup, but this would be very easy to add in. What I have done is created a single button which will toggle the state of the button and will show/hide it based on that state.
private Popup _popup; private bool isActive; private void button_Click( object sender, RoutedEventArgs e ) { if ( !isActive ) { isActive = true; var userControl = new PopupMessageUserControl(); userControl.Loaded += new RoutedEventHandler( _userControl_Loaded ); userControl.Unloaded += new RoutedEventHandler( _userControl_Unloaded ); _popup = new Popup(); _popup.Child = userControl; _popup.IsOpen = true; } else { if ( _popup != null ) { var popupMessageUserControl = _popup.Child as PopupMessageUserControl; popupMessageUserControl.OnLeave(); popupMessageUserControl.Loaded -= new RoutedEventHandler( _userControl_Loaded ); popupMessageUserControl.Unloaded -= new RoutedEventHandler( _userControl_Unloaded ); isActive = false; } } }
The final running product will look something live below. Again, the styling of the usercontrol (called PopupMessageUserControl) in my sample is 100% up to you and your needs, this was simply a POC to show how it could be done.
Dru and I were recently featured on Herding Code Podcast. In the podcast we talk about everything from package management in general to Nubular (Nu) to other package management systems (OpenWrap, Bricks, and Horn, although horn was/is slightly different) to the possibility of Microsoft releasing a package management system. It was a good time and I enjoyed doing the podcast, but the herding code guys start recording at an insane 10:30 PM! I have no idea how I made it through the whole thing and was still able to talk afterwards.
Some highlights:
Check out the herding code podcast and notes for more. I didn’t keep track of certain times for interesting bits in the beginning of the podcast, but Ben Griswold does an excellent job on the notes from the podcast.
http://herdingcode.com/?p=272
This is a follow up to my previous post. If you haven’t yet – go and read that one first. I’ll wait.
In the last post I said, that Windsor (any container in general) creates objects for you, hence it owns them, ergo its responsibility is to properly end their lifetime when they’re no longer needed.
Since as I mentioned in my previous post, Windsor will track your component, it’s a common misconception held by users that in order to properly release all components they must call Release method on the container.
container.Release(myComponent);
That’s the most important part of this post really, so pay attention.
In Windsor (every container in general) every component has a lifestyle associated with it. In short lifestyle defines the context in which an instance should be reused. If you want to have just single instance of a component in the context of the container, you give the object a singleton lifestyle (which is the default in Windsor). If you want to reuse your object in the context of a web request, you give it a lifestyle of a per-web-request and so on. Now the word context (though overloaded) is important here.
While some contexts, like web request have a well defined ends that Windsor can detect, that’s not the case for every of them. This brings us to the Release method.
Windsor has a Release method that you use to explicitly tell it “hey, I’m not gonna use this this object anymore.” Although the method is named very imperatively, which would suggest it takes immediate action, it’s not often the case. Quite a lot of time may pass between you call the method and Windsor will get the object destroyed. When the object gets really destroyed is up to its lifestyle manager, and they act differently.
If you’re now scratching your head thinking “Does Windsor really puts all the burden of releasing stuff on me?” don’t despair. The reality is – you never have to call Release explicitly in your application code. Here’s why.
Releasing a component releases entire graph. As outlined in previous section, Windsor can detect end of scope for components with most lifetimes. In that case, if you have a per-web-request ShoppingCard component that depends on transient PaymentCalculationService and singleton AuditWriter, when the request ends Windsor will release the shopping card along with both of its dependencies. Since auditwriter is a singleton releasing it will not have any effect (which is what we want) but the transient payment calculator will be releases without you having to do anything explicitly.
You obviously need to structure your application properly for this to work. If you’re abusing the container as service locator than you’re cutting a branch you’re sitting on.
This also works with typed factories – when a factory is released, all the components that you pulled via the factory will be released as well. However you need to be cautious here – if you’re expecting to be pulling many components during factory’s lifetime (especially if the factory is a singleton) you may end up needlessly holding on to the components for much too long, causing a memory leak.
Imagine you’re writing a web browser, and you have a TabFactory, that creates tabs to display in your browser. The factory would be a singleton in your application, but the tabs it produces would be transient – user can open many tabs, then close them, then open some more, and close them as well. Being a web savvy person you probably know firsthand how quickly memory consumption in a web browser can go up so you certainly don’t want to wait until you dispose of your container to release the factory and release all the tabs it ever created, even the ones that were closed days ago.
More likely you’d want to tell Windsor to release your transient tabs as soon as the user closes it. Easy – just make sure your TabFactory has a releasing method that you call when the tab is closed. The important piece here is that you’d be calling a method on a factory interface that is part of your application code, not method on the container (well – ultimately that will be the result, but you don’t do this explicitly).
UPDATE: As Mark pointed out in the comment there are certain low level components that act as factories for the root object in our application (IControllerFactory in MVC, IInstanceProvider in WCF etc). If you’re not using typed factories to provide these service and implement them manually pulling stuff from the container, than the other rule (discussed below) applies - release anything you explicitly resolve
UPDATE:
As Mark pointed out in the comment there are certain low level components that act as factories for the root object in our application (IControllerFactory in MVC, IInstanceProvider in WCF etc). If you’re not using typed factories to provide these service and implement them manually pulling stuff from the container, than the other rule (discussed below) applies - release anything you explicitly resolve
There are places where you do need to call Release explicitly – in code that extends or modifies the container. For example if you’re using a factory method to create a component by resolving another component first, you should release the other component.
container.Register(
Component.For<ITaxCalculator>()
.UsingFactoryMethod(
k =>
{
var country = k.Resolve<ICountry>(user.CountryCode);
var taxCalculator = country.GetTaxCalculator();
k.ReleaseComponent(country);
return taxCalculator;
}
)
);
This is a code you could place in one of your installers. It is completely artificial but that’s not the point. Point is, we’re using a factory method to provide instances of a component (tax calculator) and for this we’re using another component (country). Remember the rule – You have to release anything you explicitly resolve. We did resolve the country, so unless we are sure that the country is and always will be a singleton or have one of the other self-releasing lifestyles, we should release it before returning the tax calculator.
I’m still a Powershell n00b, so take my advice cum granis salis.
My situation was that I needed some 3rd party assemblies installed in the GAC on a build server. There was a little bit of churn on the assemblies, so it wasn’t just an “install once and forget”. I’m lazy, so I found a powershell script to help me out. I wanted to be able to run the script and have it install all the assemblies from the current folder in the GAC. Here is my end result:
if ( $null -eq ([AppDomain]::CurrentDomain.GetAssemblies() |? { $_.FullName -eq "System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" }) ) { [System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") | Out-Null } $publish = New-Object System.EnterpriseServices.Internal.Publish Foreach ($file in Get-Childitem "*.dll" -recurse -force) { Write-Host $file $assembly = $null if ( $file -is [string] ) { $assembly = $file } elseif ( $file -is [System.IO.FileInfo] ) { $assembly = $file.FullName } elseif ( $file -is [System.IO.DirectoryInfo] ) { Continue } else { #throw ("The object type '{0}' is not supported." -f $file.GetType().FullName) } if ( -not (Test-Path $assembly -type Leaf) ) { throw "The assembly '$assembly' does not exist." } if ( [System.Reflection.Assembly]::LoadFile( $assembly ).GetName().GetPublicKey().Length -eq 0 ) { throw "The assembly '$assembly' must be strongly signed." } Write-Output "Installing: $assembly" $publish.GacInstall( $assembly ) }
You might notice that this script is using some .NET 4.0 assemblies. Well, Powershell runs against the .NET 2.0 runtime. So executing this script will give you an error that contains this:
“This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.”
Crackers.
You can get the Powershell to use the latest runtime by hacking some registry settings. I hacked away and the script executed just fine.
reg add hklm\software\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1 reg add hklm\software\wow6432node\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1
N.B. I had to restart for these changes to take effect.
As is mentioned here, making this change to your registry can be a really bad idea. In fact, I ended having a problem where I was unable to compile a particular project due to making this change. I wasted an hour examining the code before I understand what the problem actually was. (Unfortunately, I failed to document the error.)
I advise against changing the registry and recommend sticking with the config file.
I was looking at Sharp Architecture project and as I went through the codebase (the sample application in particular) I found several spots that weren’t using Windsor in a optimal way, and few other that could really benefit from some of the new improvements in version 2.5. So instead of keeping that knowledge all to myself I though I might as well use it as an example and show the process of migration I went though with it. The guide is based on current source from SA repository, and its Northwind sample application.
We start off by copying Windsor 2.5 binaries to bin folder of SharpArchitecture.
Windsor 2.5 consists of only 2 assemblies, as compared to 4 in previous versions. Castle.MicroKernel.dll and Castle.DynamicProxy2.dll are no longer needed (the classes from these two assemblies were integrated into the two other assemblies).
Since SharpArchitecture users NHibernate which has dependency on DynamicProxy I also needed to rebuild the NHibernate.ByteCode.Castle.dll for the new DynamicProxy (which now lives in Castle.Core.dll). It may seem complicated but really was just a matter of fixing some namespaces.
Fixing Sharp Architecture was quite simple. I opened the solution, built it, watched it fail, and stared to fix references (removing references to defunct, Castle.DynamicProxy2.dll, and removing or replacing with Castle.Windsor.dll references to Castle.MicroKernel.dll)
While updating the code I also stumbled upon one breaking change in new Windsor.
ServiceSelector delegate (used in WithService.Select calls) changed signature so that its 2nd parameter is now an array of Types, not a single type. If you look at BreakingChanges.txt distributed with Windsor 2.5, you’ll find that it documents this breaking change along with suggestion how to upgrade your old code.
fix - depending on the scenario. You would either ignore it, or wrap your current method's body in foreach(var baseType in baseTypes)
In our case the former applies, so we just update the signature and move on. The project now compiles just fine.
With that done we can shift focus to the sample Northwind application. We don’t need to do anything other than upgrading references to Windsor, NHibernate bytecode provider and SharpArch to get it to compile. This does not mean that we’re done though.
The project will compile but will give us 18 errors. That’s something most users upgrading older apps will see. If you take a look at the errors you’ll see something like this:
In Windsor 2.5 all the old registration API (all AddComponent and friends methods) became obsolete, as first step towards cleaning the API of the container. All the obsolete methods points us towards alternative – supported API that we can use to achieve the same thing so we can quite easily migrate the old calls. We won’t follow the suggestions from the error messages. Instead we’ll take a step back, to look at how the registration is being done.
All the obsolete calls come from a single class – ComponentRegistrar, which looks like this:
public class ComponentRegistrar
public static void AddComponentsTo(IWindsorContainer container)
AddGenericRepositoriesTo(container);
AddCustomRepositoriesTo(container);
AddApplicationServicesTo(container);
AddWcfServiceFactoriesTo(container);
container.AddComponent("validator",
typeof (IValidator), typeof (Validator));
// private registration methods
Windsor has (and had for a very long time) a better – “official” way of doing this, using installers. To take advantage of that we’ll start by moving code from the Add*To methods, to dedicated installer types.
For example we could take the AddGenericRepositoriesTo method
private static void AddGenericRepositoriesTo(IWindsorContainer container)
container.AddComponent("repositoryType",
typeof (IRepository<>), typeof (Repository<>));
container.AddComponent("nhibernateRepositoryType",
typeof (INHibernateRepository<>), typeof (NHibernateRepository<>));
container.AddComponent("repositoryWithTypedId",
typeof (IRepositoryWithTypedId<,>), typeof (RepositoryWithTypedId<,>));
container.AddComponent("nhibernateRepositoryWithTypedId",
typeof (INHibernateRepositoryWithTypedId<,>), typeof (NHibernateRepositoryWithTypedId<,>));
and extract it to an installer:
public class GenericRepositoriesInstaller : IWindsorInstaller
public void Install(IWindsorContainer container, IConfigurationStore store)
Add(typeof (IRepository<>), typeof (Repository<>)),
Add(typeof (INHibernateRepository<>), typeof (NHibernateRepository<>)),
Add(typeof (IRepositoryWithTypedId<,>), typeof (RepositoryWithTypedId<,>)),
Add(typeof (INHibernateRepositoryWithTypedId<,>), typeof (NHibernateRepositoryWithTypedId<,>)));
private IRegistration Add(Type service, Type implementation)
return Component.For(service).ImplementedBy(implementation);
I dropped the name of the component since it’s never used in the application anyway, and I extracted common code to a helper method.
Let’s have a look at another one of these methods:
private static void AddWcfServiceFactoriesTo(IWindsorContainer container)
container.AddFacility("factories", new FactorySupportFacility());
container.AddComponent("standard.interceptor", typeof (StandardInterceptor));
var factoryKey = "territoriesWcfServiceFactory";
var serviceKey = "territoriesWcfService";
container.AddComponent(factoryKey, typeof (TerritoriesWcfServiceFactory));
var config = new MutableConfiguration(serviceKey);
config.Attributes["factoryId"] = factoryKey;
config.Attributes["factoryCreate"] = "Create";
container.Kernel.ConfigurationStore.AddComponentConfiguration(serviceKey, config);
container.Kernel.AddComponent(serviceKey, typeof (ITerritoriesWcfService),
typeof (TerritoriesWcfServiceClient), LifestyleType.PerWebRequest);
There’s quite a lot going on here. It’s using FactorySupportFacility to register a service as well as a factory that will provide instances of this service. Why does it use a factory?
public class TerritoriesWcfServiceFactory
public ITerritoriesWcfService Create()
var address = new EndpointAddress(
// I see the below as a magic string; I typically like to move these to a
// web.config reader to consolidate the app setting names
ConfigurationManager.AppSettings["territoryWcfServiceUri"]);
var binding = new WSHttpBinding();
return new TerritoriesWcfServiceClient(binding, address);
The factory provides arguments to the service, and one of these arguments is also depending on a value from the config file. How can we do this better? We have two options here. We either register the binding and endpoint address in our container as services, so that Windsor itself can provide them to the TerritoriesWcfServiceClient or we register them as inline dependencies of the service. I don’t think it makes much sense to register them as services, so we’ll go with the latter option.
public class TerritoriesWcfServiceClientInstaller:IWindsorInstaller
var address = new EndpointAddress(ConfigurationManager.AppSettings["territoryWcfServiceUri"]);
container.Register(Component.For<ITerritoriesWcfService>()
.ImplementedBy<TerritoriesWcfServiceClient>()
.DependsOn(Property.ForKey<Binding>().Eq(new WSHttpBinding()),
Property.ForKey<EndpointAddress>().Eq(address))
.LifeStyle.PerWebRequest);
We’re not using a factory here, letting Windsor create the instance for us. We’re also passing the binding and address as typed dependencies, which is a new option in version 2.5.
The last method I want to look at (as this post is already enormously big) is this:
private static void AddApplicationServicesTo(IWindsorContainer container)
AllTypes.Pick()
.FromAssemblyNamed("Northwind.ApplicationServices")
.WithService.FirstInterface());
There are two issues with it. First it calls Pick() before FromAssembly*. That’s not a big deal but in Windsor 2.5 we tried to unify the API so that the order always should be: Specify assembly –> specify components –> configure.
The other issue is that it uses FirstInterface to pick a service for a type. Problem with that is, that if type implements more than one interface, which one is “first” is undefined. It can be one on Thursdays, and the other one on Fridays. Good luck chasing issues caused by this.
Windsor 2.5 adds new option that first the purpose much better in this case – default interface. It performs matching based on type/interface name. Since we have actually just single class and interface in that assembly: DashboardService/IDashboardService they are perfect match for this. So that our installer would look like this:
public class ApplicationServicesInstaller : IWindsorInstaller
AllTypes.FromAssemblyNamed("Northwind.ApplicationServices")
.Pick().WithService.DefaultInterface());
Now having all registration enclosed in installers in our project we can change this:
ComponentRegistrar.AddComponentsTo(container);
to this:
container.Install(FromAssembly.This());
and Windsor will take care of all the rest.
That’s pretty much all it takes to upgrade the app to run on top of latest and greatest version of Windsor. In addition we introduced some new features that you likely are going to take advantage of when upgrading your apps (or starting new ones as well). I suspect there is some room for improvement in the Northwind app, and place for some other Windsor features but that perhaps should be left for another post.
Today I was trying to wrap some code in some tests (I got lazy and did not create the tests first… shot me). What I was trying to ensure was that my event handlers I passed into a method were actually being wired up for usage. Now I searched around the net for a while to see if there was a elegant solution to this problem but I could not find one. Below is the solution I came up with. Mind you this may not be a great solution, hell it may just down right suck but it works for me.
First things first, her is the method i was trying to provide coverage for
public void GetAppointments( DateTime? from, DateTime? to, EventHandler localRequestStarted, EventHandler remoteRequestStarted, EventHandler> requestFinsished ) { var currentUser = _sessionManager.GetValue(); var dataRequest = new AppointmentDataRequest( new AppointmentParameterContext( currentUser.ResourceIds, from.Value, to.Value ) ); dataRequest.LocalRequestStarted += localRequestStarted; dataRequest.RemoteRequestStarted += remoteRequestStarted; dataRequest.RequestFinished += requestFinsished; _dataManager.Fetch( dataRequest ); }
As you can see there are 3 lines in the above code where the passed in EventHandlers are being attached. I wanted to ensure this. But what you may also see is that I have no direct access to the dataRequest object which is being created in this method. That is where our handy rhino mocks library comes in. With Rhino Mocks I am able to get the pointer to the various values which are passed into methods. Check out the test below and you will see how this is done.
My unit test
[Test] public void GetAppointments_WhenCalled_EnsureWillWireupEventsCorrectly() { var dataManager = MockRepository.GenerateMock<IDataManager>(); var sessionManager = MockRepository.GenerateMock<ISessionManager>(); var currentUser = new CurrentUser(); sessionManager.Stub( x => x.GetValue<CurrentUser>() ).Return( currentUser ); var provider = new AppointmentProvider( dataManager, null, sessionManager, null ); bool localWired = false, remoteWired = false, requestFinishedWired = false; EventHandler<LocalRequestStartedEventArgs> localRequest = ( s, arg ) => { localWired = true; }; EventHandler<RemoteRequestStartedEventArgs> remoteRequest = ( s, arg ) => { remoteWired = true; }; EventHandler<RequestFinishedEventArgs<object>> requestFinished = ( s, arg ) => { requestFinishedWired = true; }; provider.GetAppointments( DateTime.Now, DateTime.Now, localRequest, remoteRequest, requestFinished ); IList<object[]> argumentsForCallsMadeOn = dataManager.GetArgumentsForCallsMadeOn( x => x.Fetch( Arg<DataRequest>.Is.Anything ) ); var dataRequest = (AppointmentDataRequest)argumentsForCallsMadeOn[ 0 ][ 0 ]; dataRequest.RaiseLocalRequestStarted(); dataRequest.RaiseRemoteRequestStarted(); dataRequest.RaiseDataRequestFinished( DataRequestType.UserLogin, DataRequestResult.Unknown, null, null ); Assert.That( localWired, Is.True ); Assert.That( remoteWired, Is.True ); Assert.That( requestFinishedWired, Is.True ); }
As you can see this test has a lot going on, but let me explain some of this for you.
1) First thing we need to do is create a few local variables which will hold the state of the event firing
2) Next we want to create local copies of our event delegates in order to push them into our method
3) Next is time for the Rhino Mock magic. Notice how I am calling the GetargumentsForCallsMadeOn() method. This is a method in Rhino Mocks which allows me to reach into the call stack and pull out the values which were pushed into a method when it was called. I then cast the argument i want to its native type.
4) In order to ensure the events were wired up I need to call the various ‘raise’ methods in order to trigger them. Doing this should cause my local state holders for the events to be changed and this is what we actually want to ensure
5) Ensure the event state variables were set to true.
There you have it, a simple (well kinda) way to ensure that your events have been registered correctly in your code.
Exactly one month after beta 2, I’m happy to announce that Windsor, as well as Castle Core (which now includes DynamicProxy and Dictionary Adapter) 2.5 are officially released.
Single .zip contains the following versions:
For the list of changes see announcement for beta 1, and beta 2 or changes.txt file in the package. Since beta 2 the following changes were made:
For now we have a single sample application (Silverlight 4 app), created by Hadi Eskandari. You’re still welcome to contribute more apps, and hopefully soon we’ll have more of them.
While not strictly related to the release, we also deployed a new issue tracker, which should be much easier to use.
The package is here (Core with DynamicProxy and Dictionary Adapter) and here (Windsor with Logging Facility and Synchronize Facility). Enjoy.
Before our WP7 detour, we were deep in the thick of Actions. I mentioned that there was one more compelling feature of the Actions concept called Coroutines. If you haven’t heard that term before, here’s what wikipedia* has to say:
In computer science, coroutines are program components that generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, iterators,infinite lists and pipes.
Here’s one way you can thing about it: Imagine being able to execute a method, then pause it’s execution on some statement, go do something else, then come back and resume execution where you left off. This technique is extremely powerful in task-based programming, especially when those tasks need to run asynchronously. For example, let’s say we have a ViewModel that needs to call a web service asynchronously, then it needs to take the results of that, do some work on it and call another web service asynchronously. Finally, it must then display the result in a modal dialog and respond to the user’s dialog selection with another asynchronous task. Accomplishing this with the standard event-driven async model is not a pleasant experience. However, this is a simple task to accomplish by using coroutines. The problem…C# doesn’t implement coroutines natively. Fortunately, we can (sort of) build them on top of iterators.
There are two things necessary to take advantage of this feature in Caliburn.Micro: First, implement the IResult interface on some class, representing the task you wish to execute; Second, yield instances of IResult from an Action.** Let’s make this more concrete. Say we had a Silverlight application where we wanted to dynamically download and show screens not part of the main package. First we would probably want to show a “Loading” indicator, then asynchronously download the external package, next hide the “Loading” indicator and finally navigate to a particular screen inside the dynamic module. Here’s what the code would look like if your first screen wanted to use coroutines to navigate to a dynamically loaded second screen:
using System.Collections.Generic; using System.ComponentModel.Composition; [Export(typeof(ScreenOneViewModel))] public class ScreenOneViewModel { public IEnumerable<IResult> GoForward() { yield return Loader.Show("Downloading..."); yield return new LoadCatalog("Caliburn.Micro.Coroutines.External.xap"); yield return Loader.Hide(); yield return new ShowScreen("ExternalScreen"); } }
First, notice that the Action “GoForward” has a return type of IEnumerable<IResult>. This is critical for using coroutines. The body of the method has four yield statements. Each of these yields is returning an instance of IResult. The first is a result to show the “Downloading” indicator, the second to download the xap asynchronously, the third to hide the “Downloading” message and the fourth to show a new screen from the downloaded xap. After each yield statement, the compiler will “pause” the execution of this method until that particular task completes. The first, third and fourth tasks are synchronous, while the second is asynchronous. But the yield syntax allows you to write all the code in a sequential fashion, preserving the original workflow as a much more readable and declarative structure. To understand a bit more how this works, have a look at the IResult interface:
public interface IResult { void Execute(ActionExecutionContext context); event EventHandler<ResultCompletionEventArgs> Completed; }
It’s a fairly simple interface to implement. Simply write your code in the “Execute” method and be sure to raise the “Completed” event when you are done, whether it be a synchronous or an asynchronous task. Because coroutines occur inside of an Action, we provide you with an ActionExecutionContext useful in building UI-related IResult implementations. This allows the ViewModel a way to declaratively state it intentions in controlling the view without having any reference to a View or the need for interaction-based unit testing. Here’s what the ActionResultContext looks like:
public class ActionExecutionContext { public ActionMessage Message; public FrameworkElement Source; public object EventArgs; public object Target; public DependencyObject View; public MethodInfo Method; public Func<bool> CanExecute; public object this[string key]; }
And here’s an explanation of what all these properties mean:
Bearing that in mind, I wrote a naive Loader IResult that searches the VisualTree looking for the first instance of a BusyIndicator to use to display a loading message. Here’s the implementation:
using System; using System.Windows; using System.Windows.Controls; public class Loader : IResult { readonly string message; readonly bool hide; public Loader(string message) { this.message = message; } public Loader(bool hide) { this.hide = hide; } public void Execute(ActionExecutionContext context) { var view = context.View as FrameworkElement; while(view != null) { var busyIndicator = view as BusyIndicator; if(busyIndicator != null) { if(!string.IsNullOrEmpty(message)) busyIndicator.BusyContent = message; busyIndicator.IsBusy = !hide; break; } view = view.Parent as FrameworkElement; } Completed(this, new ResultCompletionEventArgs()); } public event EventHandler<ResultCompletionEventArgs> Completed = delegate { }; public static IResult Show(string message = null) { return new Loader(message); } public static IResult Hide() { return new Loader(true); } }
See how I took advantage of context.View? This opens up a lot of possibilities while maintaining separation between the view and the view model. Just to list a few interesting things you could do with IResult implementations: show a message box, show a VM-based modal dialog, show a VM-based Popup at the user’s mouse position, play an animation, show File Save/Load dialogs, place focus on a particular UI element based on VM properties rather than controls, etc. Of coarse, one of the biggest opportunities is calling web services. Let’s look at how you might do that, but by using a slightly different scenario, dynamically downloading a xap:
using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.ComponentModel.Composition.ReflectionModel; using System.Linq; public class LoadCatalog : IResult { static readonly Dictionary<string, DeploymentCatalog> Catalogs = new Dictionary<string, DeploymentCatalog>(); readonly string uri; [Import] public AggregateCatalog Catalog { get; set; } public LoadCatalog(string relativeUri) { uri = relativeUri; } public void Execute(ActionExecutionContext context) { DeploymentCatalog catalog; if(Catalogs.TryGetValue(uri, out catalog)) Completed(this, new ResultCompletionEventArgs()); else { catalog = new DeploymentCatalog(uri); catalog.DownloadCompleted += (s, e) =>{ if(e.Error == null) { Catalogs[uri] = catalog; Catalog.Catalogs.Add(catalog); catalog.Parts .Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly) .Where(assembly => !AssemblySource.Instance.Contains(assembly)) .Apply(x => AssemblySource.Instance.Add(x)); } else Loader.Hide().Execute(context); Completed(this, new ResultCompletionEventArgs { Error = e.Error, WasCancelled = false }); }; catalog.DownloadAsync(); } } public event EventHandler<ResultCompletionEventArgs> Completed = delegate { }; }
In case it wasn’t clear, this sample is using MEF. Furthermore, we are taking advantage of the DeploymentCatalog created for Silverlight 4. You don’t really need to know a lot about MEF or DeploymentCatalog to get the takeaway. Just take note of the fact that we wire for the DownloadCompleted event and make sure to fire the IResult.Completed event in its handler. This is what enables the async pattern to work. We also make sure to check the error and pass that along in the ResultCompletionEventArgs. Speaking of that, here’s what that class looks like:
public class ResultCompletionEventArgs : EventArgs { public Exception Error; public bool WasCancelled; }
Caliburn.Micro’s enumerator checks these properties after it get’s called back from each IResult. If there is either an error or WasCancelled is set to true, we stop execution. You can use this to your advantage. Let’s say you create an IResult for the OpenFileDialog. You could check the result of that dialog, and if the user canceled it, set WasCancelled on the event args. By doing this, you can write an action that assumes that if the code following the Dialog.Show executes, the user must have selected a file. This sort of technique can simplify the logic in such situations. Obviously, you could use the same technique for the SaveFileDialog or any confirmation style message box if you so desired. My favorite part of the LoadCatalog implementation shown above, is that the original implementation was written by a CM user! Thanks janoveh for this awesome submission! As a side note, one of the things we added to the CM project site is a “Recipes” section. We are going to be adding more common solutions such as this to that area in the coming months. So, it will be a great place to check for cool plugins and customizations to the framework.***
Another thing you can do is create a series of IResult implementations built around your application’s shell. That is what the ShowScreen result used above does. Here is its implementation:
using System; using System.ComponentModel.Composition; public class ShowScreen : IResult { readonly Type screenType; readonly string name; [Import] public IShell Shell { get; set; } public ShowScreen(string name) { this.name = name; } public ShowScreen(Type screenType) { this.screenType = screenType; } public void Execute(ActionExecutionContext context) { var screen = !string.IsNullOrEmpty(name) ? IoC.Get<object>(name) : IoC.GetInstance(screenType, null); Shell.ActivateItem(screen); Completed(this, new ResultCompletionEventArgs()); } public event EventHandler<ResultCompletionEventArgs> Completed = delegate { }; public static ShowScreen Of<T>() { return new ShowScreen(typeof(T)); } }
This bring up another important feature of IResult. Before CM executes a result, it passes it through the IoC.BuildUp method allowing your container the opportunity to push dependencies in through the properties. This allows you to create them normally within your view models, while still allowing them to take dependencies on application services. In this case, we depend on IShell. You could also have your container injected, but in this case I chose to use the IoC static class internally. As a general rule, you should avoid pulling things from the container directly. However, I think it is acceptable when done inside of infrastructure code such as a ShowScreen IResult.
I hope this gives some explanation and creative ideas for what can be accomplished with IResult. Be sure to check out the sample application attached. There’s a few other interesting things in there as well.
* When I went to look up the “official” definition on wikipedia I was interested to see what it had to say about implementations in various languages. Scrolling down to the section on C#…Caliburn was listed! Fun stuff.
** You can also return a single instance of IResult without using IEnuermable<IResult> if you just want a simple way to execute a single task.
*** If you want a sample of a truly awesome plugin we will be adding to the recipes section soon, check this out!
James Senior posted on his Twitter account:
“oh dear lord no. why intel, why? http://ow.ly/2s2dm reminds me of when Intel got into the hosting business. http://ow.ly/2s2fT”
James is referencing an article posted by the BBC on the recent news of Intel’s takeover of McAfee for 7.68 Billion. While I agree with James on Intel’s foray into hosting – of course hindsight is 20/20 – I disagree with his position on this particular deal and here’s why.
Despite the rapid growth over the last 15 years of PC’s, viruses are still problematic. Despite continual efforts at training the masses, viruses still are far too prevalent. Additionally the methods for exploitation continue to spread and evolve faster than the education can keep up with. For example, by now, the vast majority – save your grandmother – knows not to open executables sent via email (largely this practice is blocked at the email level anyway). A smaller, but still growing population have learned to not open attachments from people you don’t know. And yet viruses at times runs rampant.
The virus landscape has largely changed with a more sophisticated modern day virus writer. He/she is no longer malicious in their intent to infect your computer but instead often plant malware to consume and distribute private information on your computer. Certainly dangerous viruses still exist, but there’s less money in that.
Given that education can’t keep up (or thus far hasn’t proven to be able to keep up) with the changing exploits and security software saturation is still less than 100%, I see the move by Intel as a positive one. Imagine virus protection at the chip level. The virus uses the chip and it’s processing to do it’s damage. If the chip can refuse access to the virus, the virus is rendered ineffective.
In an environment with increasing questions/concerns about security threats, a chip maker who can offer it’s customers virus protection has a significant advantage over it’s competitors. Additionally, every computer has a CPU and saturation into the market would be swift as computers with this technology would be introduced into the market as people replaced their old PC’s.
In an interesting twist to this story, I could see Microsoft having interest in this particular marriage. Largely portrayed by many as insecure, a chip with protection renders the discussion about OS security potentially moot. Whether Microsoft would admit to it or not, it has skin in this game.
Overall, I think Intel’s choice is a strategic one and might prove be a great one. After over two decades of security software, software hasn’t been the answer. That doesn’t mean software couldn’t be the answer, however history has thus far shown software as a weak solution. It’s time for a game-changer. This could be the road to that much needed change.
Time will tell…
The enthusiastic and dedicated Alec Whittington took over as lead developer of S#arp Architecture earlier this year. Since then, he's worked hard to maintain a clear direction, to further improve S#arp Architecture while adhering to its original principles, and to include additional great talent in the core development team including the guys behind the Who Can Help Me project sample (Howard van Rooijen, James Broome, and Jon George). Through a lot of hard work, the team has released S#arp Architecture 1.6. Alec's announcement:
It has been a while since the last release and we have had some nice features added. The biggest items in this release are:
Fluent NHibernate 1.1 - We are now using version 1.1.0.635. The AutoMappingPersistenceGenerator has been updated to use the new bits as well. NHibernate Configuration caching has now been added CRUD forms now enable client side validation
This release was almost 100% done by the community, that is amazing! I would like to thank everyone who contributed to this release. I truly appreciate your help and feel that it benefits the community greatly.
Whats Next?
This will be the last version to support VS 2008 as well as .NET 3.5. We will keep a branch available for the community to maintain, but no further development will be done against this branch. The next version will be tagged 2.0, support only VS 2010 and .NET 4.0.
As you may have heard, we are in the process of a partial rewrite. We are working on increasing the code coverage as well as some new bits. While I will not go into details, lets just say one of our focuses is to make sure the installation and solution creation become easier and less problematic. We are also going with a more Who Can Help Me solution structure for not only the S#arp Architecture project, but also the default template. We all felt that this structure further reinforced the overall project goal of good design practices. We are also going to try and deliver better documentation as well as an expanded line of samples. On that note, the Who Can Help Me application as joined the Northwind sample as an official sample. There are many many other things as well, but they are still in the early stages, so we will leave them there for now. Once they get better defined, we will let everyone know.
I needn't state how pleased I am to see S#arp Architecture not just surviving, but thriving. I have immense appreciation to Alec, the core team, and the S#arp community for the continued support and progress of this project.
If you're new to S#arp Architecture, I invite you to learn more at http://wiki.sharparchitecture.net/.
Billy McCafferty
About The CodeBetter.Com Blog NetworkCodeBetter.Com FAQOur Mission Advertisers should contact Brendan
Subscribe Google Reader or Homepagedel.icio.us CodeBetter.com Latest ItemsAdd to My Yahoo!Subscribe with BloglinesSubscribe in NewsGator OnlineSubscribe with myFeedsterAdd to My AOLFurl CodeBetter.com Latest ItemsSubscribe in Rojo
Member ProjectsDimeCasts.Net - Derik Whittaker
Friends of Devlicio.usRed-Gate Tools For SQL and .NETNDependSlickEdit SmartInspect .NET Logging NGEDIT: ViEmu and Codekana LiteAccounting.Com DevExpressFixxNHibernate ProfilerUnfuddle Balsamiq MockupsScrumyJetBrains - ReSharper <-- NEW Friend!
Site Copyright © 2007 CodeBetter.Com Content Copyright Individual Bloggers