Tuesday, January 31, 2012

Autofac and WCF Lifetime Issues

I am building a fairly simple WCF service and decided to use Autofac / Autofac.Integration.Wcf for (admittedly very simple) dependency injection.

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() twice in one of my service methods witht he expectation that each call to the service method would create a single new instance of BusinessService, but the two calls in the one method would return the same instance. Unfortunately this was not the case, and a single instance was reused throughout all my service method invokations.

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

For the last few months twitter has been abuzz with TFS hate, and I always wondered exactly why.

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

I generally don't like to use strongly typed configuration sections, but I'm working on a project that uses them very heavily and just encountered an annoying issue.

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

One of the major disadvantages of being a consultant is that you usually have to fit in with the incumbent way of doing things. Despite being able to bring knowledge and experience to a team, you are often found toe-ing the line despite your best efforts.

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.