Thursday, March 8, 2012
MVC4
With the release of MVC4 beta I decided to really try and get stuck into JavaScript and at the same time work on Mobile application development for rich internet apps.
One thing that I think is really lacking in the MVC javascript demos however is an explanation of the basic components of the projects. All the demos highlight how easy it is to load and manipulate data through the web api, and bind to elements on the page, but there is very little on the application plumbing, how pages are rendered, how navigation works, how the partial views are rendered to popups, etc. All of this requires diving into the code to work it out.
So hopefully in the coming weeks I'll post a few guides on these 'basics' as I start to build up my own knowledge.
Saturday, February 11, 2012
5 Minutes of Android from a .net dev
Introduction
I have been part of a casual group of senior developers working on building a standard development platform for our teams, and have been using it for a few simple trial projects quite successfully. The original design was to support desktop, web, and Windows Phone development, with the primary focus being the core tiers (data/business) with the presentation layers currently fairly underdeveloped.
I have produced effective WP7 applications using this framework however, so I figured I would build an Android app to get some insight into how much effort would be involved in supporting multiple native applications.
Backend
I started with a simple design, a ratings system where users can rate, and view the average rating, for a list of items. As Android doesn’t support SOAP very well, I decided to expose my services via webHttp (REST) endpoints, which works quite well with the ratings model that I am building.
I had a few issues setting up Json support through WCF, for a couple of reasons.
Firstly I was using DataContract(IsReference=true) to support the data contract serialisation of my entities, which is not supported by DataContractJsonSerializer. This was required to prevent circular references in my entity design for previous projects. The solution was to turn this off, and ignore the circular references from my entities using IgnoreDataMember attributes.
As always, as this was within the WCF layer, the errors were woefully inadequate, and it took a while to actually identify this as the issue :/
Secondly, I downloaded and installed cUrl to test my POST/PUT calls, and getting the exact right quotes/escaping strategy for the Json parameter was a pain. In the end I needed the entire parameter enclosed in single quotes, and each double quote for the key/value pairs needed to be escaped with a standard escape character (\) .
Android
So I now had a RESTful service that android would be able to access quite easily, so on to the android development part.
- Getting the tools
- This was fairly easy, Google has a very simple guide on how to get the SDK, as well as links to appropriate IDEs
- The development can be done in a variety IDE’s, including eclipse, but for a change I decided to go with Telerik IntelliJ Idea, which has “built in” android support.
- It was a bit of a process to download all the components for development. Once the SDK was installed there were then a number of sub-components to download.
- And then I needed the right Java Versions, with android only working on Java 1.6 meaning I needed to sign up for an Oracle account to download a legacy jdk.
- Hello World
- IntelliJ IDEA was good here, creating a new android project was straight-(ish) forward.
- Much like java projects in general, the code, assets, and resources were scattered all over a number of folders, but at least the build files were all set up and everything built up front.
- While IDEA has no graphical designer, it does have a preview. I will need to work out how I can support test data in the designer to make sure things look right.
- Testing
- Setting up an emulator was very simple, and deploying was automatic when debugging.
- Debugging was very slow, I would definitely switch to a real device for tracing/debugging in anger.
- Next Steps
- Web Access
- Getting a single http request to my REST service was easy
- note, do not use localhost (yeah i should have known this from my WP7 apps too)
- Data Binding
- Not quite there yet, but it is not as simple as I expected – there is no JSON binding support off the bat, and binding list data actually involves creation of arrays of hashmaps. This was a big surprise.
- Page Navigation
- Haven’t looked at this yet
- UI Design
- Haven’t looked at this yet
- Web Access
Conclusion
I had a lot of reservations on how hard it would be to make a simple android app, but offloading all the logic to the service layer, using RESTful services and designing your application flow for the mobile form factor, it looks like it can be done with fairly minimal effort.
Obviously providing ‘local’ device processing and resources (inputs etc) will complicated this dramatically, but for LOB systems it is definitely feasible. Providing a native WP7 and Android front-ends is definitely within reach of our application framework.
Thursday, February 2, 2012
Autofac and A Simple Plugin Design
The plan was to generate the components as independent assemblies so that they could be implemented and deployed independantly of the service. This also meant I needed XML configuration to register each new component.
The implementation would be to instantiate a Service, which had an IProcessor as a dependency
public Service(Common commonService, IProcessor processor)
I then register the service as a named service, which is named after the processor that is to be created. However, the named server needed to be configured to create a named instance of the IProcessor when resolved (as the WebService resolves the Service, not the IProcessor).
builder.Register(c => new Service(c.Resolve<TrimCommon>(), c.ResolveNamed<IProcessor>("CustomProcessor"))).Named<Service>("CustomProcessor");
In order to resolve the Service I need to register my CustomProcessor, which is where the 'trickyness' kicks in. I didn't want to add each CustomProcessor as a reference to my service, as that would be difficult to manage, so I could not just register the type Fluently.
This meant I had to go back to XML (eewww, spring.net) to register my IProcessor implementations. This was still very easy
<component type="CustomProcessor, CustomProcessor" service="IProcessor, Common" name="CustomProcessor" instance-scope="per-lifetime-scope" />
So in code, when I resolve
Service service = getInstanceContext().ResolveNamedI get a Service with the appropriate processor.("CustomProcessor");
Unfortunately I realised that when trying to resolve the CustomProcessor class this failed, as it was not loaded into the AppContext, and did not exist in the GAC. To fix this I had to handle the AppDomain.CurrentDomain.AssemblyResolve event and load the assembly manually.
The code below handles the event and loads the assembly if it exists in the "plugins" folder of the running webservice
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
System.IO.DirectoryInfo folder = new System.IO.DirectoryInfo(this.Server.MapPath("/plugins"));
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
System.IO.FileInfo[] files = folder.GetFiles("*.dll");
foreach (System.IO.FileInfo file in files)
{
try
{
Assembly assembly = Assembly.LoadFrom(file.FullName);
if (assembly.FullName.Substring(0, assembly.FullName.IndexOf(',')) == args.Name)
{
return assembly;
}
}
catch (Exception)
{
return null;
}
}
return null;
}
Tuesday, January 31, 2012
Autofac and WCF Lifetime Issues
I have previously used Unity, with a custom wcf scoped lifetime manager, but I have heard good things about autofac.
Setting up the WCF instance was pretty straight forward following the wiki for a IIS hosted server, and I could immediately use the service.
The next step was to configure the service instance PerCall since I don't want session management, which was also straight forward.
Finally I wanted to register a dependency for the service, which caused some confusion, partly because I was 'doing it wrong', and partly because some of the guides I had seen were wrong.
My registration is shown below, and is based on the Autofac wiki examples
var builder = new ContainerBuilder();
builder.RegisterType<WcfService>();
builder.RegisterType<BusinessService>().InstancePerLifetimeScope();
AutofacHostFactory.Container = builder.Build();
The BusinessService is scoped as InstancePerLifetimeScope, which combined with the AutofacHostFactory definition in the service host markup should generate a new instance per WCF call.
I then called AutofacHostFactory.Container.Resolve
I should have known better and had the BusinessService as a dependency to my service constructor (which was indeed a misdemeanor) BUT, it took a considerable amount of time to find out why the manual service resolution was not respecting the expected Lifetime management. As it turns out, the AutofacHostFactory.Container was not the correct container to use, and now that I think of it, I can understand why, but there is very little description over what happens in the service configuration within Autofac.
Registering the container in the AutofacHostFactory actually creates an Autofac container on the Host Factory itself, which is why the resolution returned a common instance each time, even between calls. Obvious yes, but the code to get the actual container was far less obvious. It wasn't until I saw this 'bug request' that I understood what had happened.
The Autofac service host factory registers a new container lifetime when the service is created, and the only way to get it is to obtain it from the current WCF OperationContext. In Unity this was more explicit because I implemented the Lifetime Manager myself, but in Autofac the Integration.Wcf libraries which things a little more black box, and the lack of documentation was frustrating.
Anyway, as I said, I did it wrong to begin with - adding the BusinessService as a constructor dependency resoved the dependency exactly as I originally expected, but it can definitely be confusing for a developer as they cannot call resolve() on the same container they register it (on the AutofacHostFactory in this case).
Wednesday, January 25, 2012
Why the TFS Hate
Sure there are some annoyances, but on the whole as a full SDLC tool, TFS is a pretty comprehensive and cohesive tool.
It integrates source control, task management, automated builds and testing into a single system, and handles each component pretty well.
Source Control
+ good branching, merging, labelling support
+ good IDE integration
- not as good as a DCVS (such as git)
- ties source code to source control, a massive pet hate and has caused countless issues in the past
Task Management
+ flexible enough to support release planning, resourcing, task management, bug tracking, etc
+ integrates with build and testing components
+ integrates with the IDE
+ fairly easy to modify
- flexibility poor is relative to something like JIRA
Automated Builds
+ flexible
+ integrates with the IDE
+ simple to set up
+ integrates with Unit Testing (and Test Manager for deployment/UI testing)
- complex to modify
Testing (via test manager)
+ integrates with task management (test failures can generat bugs)
+ integrates with builds (you can define a set of automated UI tests to execute on build success)
As a single system nothing comes close to this level of functionality and flexibility, and despite its warts it does work pretty well.
Saying that, I can name off the top of my head better alternatives for each component, such as Git/Mercurial for source control, TeamCity for builds, HP or Rational Test Managers, JIRA for task management/workflow. Some of these integrate with TFS or Visual Studio to varying levels, but setting them up and day to day integration between these systems is not going to be as cohesive as a single TFS solution.
Granted I know in the past I have struggled to correctly set up TFS, Sharepoint, Reporting Services, Test Center, and HyperV to all work correctly, so perhaps configuring all these external systems is not as difficult as I think.
Git and TeamCity are definitely items I want to become familiar with if only to find out what the hype is all about, but I again reiterate that I don't really understand all the hate with TFS.
Perhaps more experience with these other systems will turn me into a TFS hating ragaholic too :)
Monday, January 23, 2012
Strongly Typed Configuration Sections
When you have a configuration collection such as shown below, there is no way to access the value of customAttribute in the your strongly typed collection class.
<folderlist customattribute="value">
<clear>
<add attribute1="value" attribute2="value">
<add attribute1="value" attribute2="value">
<folderlist>
The link below shows an example of how this can be resolved, but it is a bit nasty.
http://www.frankwisniewski.net/2011/12/how-to-use-a-configurationelementcollection-with-custom-attributes/
One thing to note is that in your class definition, you cannot use the [ConfigurationProperty] attribute on the property exposing the attribute, otherwise the property will not be identified as an unrecognised attribute and so your code will never be hit..
Friday, January 20, 2012
Consultancy Politics
In the past I have been in positions where I have been given the mandate to implement sweeping changes to a project development processes, but was blocked from implementing all but the smallest of these changes in an effort to appease staff that just would not make any effort to change.
In other locations I have seen permanent developers with so many years invested in a certain way of doing things that they are unwilling to accept constructive criticism or alternate views. Of course their expertise in these systems makes them invaluable and inviolate, and so the status quo continues.
Of course one of the things I have been learning is how to better introduce change and keep team morale high, so I am getting better at this, but sometimes you just wish that you could put the politics aside and just make things happen.