Castle Windsor - resolve dependencies on an existing object instance
Being able to configure an existing object resolving all its dependencies sometimes can be useful, but it can indeed be dangerous because you are mixing two different techniques of creating and managing objects lifecycles, I will not discuss why this can be troublesome, because it’s a very long and complex discussion to do in this short blog post.
Nonetheless it happened in a couple of situation that I needed to configure an already existing instance of an object, but Castle Windsor doesn’t have direct support for this scenario (Unity has a Buildup() function to do the job).
The easiest thing you can do is rely on Reflection to cycle through all your properties and ask the container to resolve the dependencies; here are a couple of extension methods that work well for me (they can be further extended to cover some more cases):
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using Castle.MicroKernel.Resolvers.SpecializedResolvers; using Castle.Windsor;
NHibernate - prepare_sql and some considerations on mapping very long string fields
Recently I’ve switched some of my applications from NHibernate 2.1.x to NHibernate 3, everything was working fine until I encountered a ‘strange behavior’ with the mapping of long string fields (those that should be mapped to nvarchar(max) and varchar(max)...yes I use Microsoft Sql Server as my database engine): using the standard mapping the field are correctly mapped to nvarchar(max), but during the saving operation the data gets truncated.
The trouble arise due to some small modifications to the SqlClinetDriver that were made to optimize the reuse of the query plan Sql Server will generate, you can enable the same feature in NHibernate 2.1.x setting the ‘prepare_sql’ configuration option to true.
Basically the problem is in the way the parameters of the SqlCommand are generated: without using prepare_sql=true the length of the string parameter is computed on the the data you pass in (ie: ‘aaa’ is represented by string(3)) and this is limiting the database engine capability of reusing query plans (more info in a link later on); but you can map an nvarchar(max) column like this:
<property name="StringHugeLength" column="StringHugeLength" type="string" length="10000" />
Tale of an ‘asp:Content control that do not correspond with asp:ContentPlaceHolder’ Master Page Error
If, like me, you are so unlucky to encounter the infamous:
‘The page has one or more <asp:Content> control that do not correspond with <asp:ContentPlaceHolder> control in master page.’
Figure 1 - The designer showing the master page error
error message when dealing with Asp.Net pages that actually use a master page, and you are unable to use the designer to drop and configure controls (raise your hand if you still use the designer instead of doing everything by hand!) you can do the following thing:
- go for the obvious resolution and check for the names of the content place holders.
If the problem still persists and you’re sure your content controls and content place holders are correctly mapped to each others (you can let the wizard generate the page for you) and moreover everything actually works at runtime (even the designer for the master page works!), the error is surely somewhere in the HTML markup and this very informative error message won’t help you find it out.
I started looking at the markup and everything seemed ok to me, even a friend of mine confirmed me the markup was ok...until I started looking very carefully and spotted the problem: this page was derived from an old project and maintained by lot of persons...so it ended having some markup and HUGE portions of the page commented out, the master page had some code like this:
... <div id="divCentralBlock"> <div id="header_down"> </div> <div class="line"> </div> <%-- Breadcrumb --%> <%-- <div id="SiteMap_Contenitore"> <asp:SiteMapPath ID="MainSiteMapPath" runat="server" PathSeparator=" : " CssClass="fnsize76pr" CurrentNodeStyle-CssClass="currentNode" NodeStyle-CssClass="node" SiteMapProvider="SiteMapPath" meta:resourcekey="MainSiteMapPathResource1" Visible="false" Enabled="false"> <CurrentNodeStyle CssClass="currentNode" /> <NodeStyle CssClass="node" /> </asp:SiteMapPath> <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" /> <%-- <cc1:scriptmanager id="smAtlas" runat="server"></cc1:scriptmanager> --%> <%-- </div> ... a lot more commented code wiped out --%> <div id="contentBox"> <div id="contentTitle"> <asp:ContentPlaceHolder ID="TitlePlaceHolder" runat="server"> </asp:ContentPlaceHolder> </div> <div id="contentBody"> <div> <asp:ContentPlaceHolder ID="MainPlaceHolder" runat="server"> </asp:ContentPlaceHolder> </div> </div> </div> </div> ...
Spot Hidden Exceptions using IntelliTrace
Recently I’ve been able to replace my Visual Studio 2010 Professional with Visual Studio 2010 Ultimate and the first feature I wanted to try was IntelliTrace, to see how it could help me debug and improve the quality of my software.
After giving a look at what it’s capable the first and simple way I used it was to look at all the exception messages raised by my applications; just looking at them I was able to discover and eliminate some ‘hidden’ problem which were simply eaten up the framework (in case of bindings errors for example) or by a wrong exception handling strategy that was implemented in code.
To enable IntelliTrace go to Tools -> Options and look for the IntelliTrace section there, you will see the following dialog:
Figure 1 - IntelliTrace Options
If you want to enable detailed information for the call tree enable the second option, but it will slow down your debugging experience a lot, so do it if you really need those information; I will also suggest you to check the advanced tab and increase the default size of the maximum amount of disk space for each recording.
Run the application with the debugger attached and when you break it you can analyze the IntelliTrace log:
Figure 2 - IntelliTrace in action, full event log
Clicking on an entry will open up the corresponding source code file and will highlight the line of interest. The default view is quite messy, because it contains logs for each type of event you asked for in the IntelliTrace Options, you can filter it up easily and show only what you want to focus on (the exceptions at the moment).
Figure 3 - Filtering the data
Wow! I never expected that my application raised so many exceptions under the hood, so I started to look at them to see if I could fix them. Inspecting this log you can see all the exceptions that ‘flows’ out of your direct control. Some of them are particularly nasty, like the ones originated from the binding system, take the following one as example:
Figure 4 - Analyzing a single exception.
Here we have a binding to a ComboBox which should hold a list of names of nations, using the software everything was working well: I could see the nations and select them and the value was correctly saved. But internally we had a System.ArgumentException that was throw and eaten up by the binding framework...why? looking at the code it’s quite clear: we are making a binding with a list of strings but we’ve also specified DisplayName and DisplayValue (maybe this control was previously in binding with something else) and this is a mistake we ignored because it has no evident effect.
The binding framework just ignores those two values...but nonetheless an avoidable exception has been thrown and captured; the solution in this case is easy: remove the assignments to DisplayMember and ValueMember.
Using IntelliTrace in this way and carefully looking at the logs I was able to remove a lot of those hidden exceptions (especially when dealing with bindings) with an overall improvement of the quality (and performance) of the application.
Related Content
- NUnitit: Visual Studio Addin to support NUnit and some customizations to it (26/08/2015)
- Resharper and the OutOfMemoryException problem (26/08/2015)
- Visual Studio 2010 designer error: Value cannot be null. Parameter name: objectType (26/08/2015)
- VS2008 SP1 + PowerCommands = Toolbox AddItems...Crash! (26/08/2015)
- How to update your TFS Workspace after CodePlex upgrade to TFS2010 (26/08/2015)
- More related document (10)
A Windows Live Essentials Suite Beta is out...how to workaround the ‘no internet connection’ setup problem
A new version of the Windows Live Essential Suite was released on August the 17th, you can get it here (at your own risk!); if you want to try it out you can have a very bad surprise:
after having chosen the applications you want to install, at the end of the setup the whole procedure might fail with a very informative ‘No internet connection’ error message.
You can have a look at the real problem looking at the Windows Live setup log (located in: C:\ProgramData\Microsoft\WLSetup\Logs), which is usually a missing dependency or something similar.
In my case it seemed the installer was trying to download a language pack (Italian, in my case) which is not currently available and that caused the setup process to stop.
Switching all the locale information of my system to the ‘United States’ language didn’t solved the problem.
The trick to overcome this problem is simple:
- uninstall all your current Windows Live Essentials
- go to: “C:\Program Files\Common Files\Windows Live\.cache” and clean it up, this is the folder where the setup files will be downloaded
- run the setup again and when it fails hit ‘Cancel’
- go to the previous folder and rerun all the setup modules you find inside each sub-directory.
Everything should work now! (At least it did for my installation).
I’m still not able to log in MSN Messenger due the the nasty 80040154 error, it seems no-one is able to discover what’s causing it, but now I can use and test the new Live Writer again (and I’m happy with that).
Related Content
- A Windows Live Essentials Suite Beta is out...hot to workaround the ‘no internet connection’ setup problem (26/08/2015)
- Dexter is growing: Dynamic Pages and better Windows Live Writer support (06/02/2010)
- Build: Windows 8 (26/08/2015)
- Winforms: improving rendering performances with BackgroundImage and BackgroundImageLayout (26/08/2015)
- HP ProLiant MicroServer, Windows 7 or Vista installation issues (26/08/2015)
- More related document (6)
NHibernate 3 - Extending the Linq Provider to fix some System.NotSupportedException
With the release of the new version NHibernate (3.0 alpha1), I’ve decided to give it a try and branch my current solution to switch to this new version and see hoe it goes.
I was especially interested in the new Linq support, cause I’ve decided to use it as the basis for my data access strategies.
After the necessary reference changes I run all my test suit...and I had bad news from the Linq provider in the form of some System.NotSupportedException like this one:
“UnitTest.Test03_Linq.QueryWithEqualsGuid:
System.NotSupportedException : Boolean Equals(System.Guid)”
Being NHibernate an open source project, instead of bothering the guys responsible for the project, my first approach is always to look at the code; so I downloaded the trunk and started looking around at the Linq provider. Watching how Equals() methods are handled by the parser it comes out fast that only the specific version to deal with strings is currently supported [bool Equals(string)], all other types have to rely on the ==operator.
But in my code I had a lot of filters based on Equals() call for various object types (int, guid and so on...) and I didn’t wanted to touch that code especially considering that with the previous Linq provider everything was working well.
However the solution is easy, just extend the default EqualsGenerator adding the support for the missing methods; but I didn’t wanted to compile a specific ‘patched’ version of NHibernate and this post from Fabio Maulo confirmed me you can easily extend the Linq provider. Great! That’s was exactly what I was looking for!
I started working on it and I had my second surprise . The Linq provider was subhect of a heavy refactoring activity to provide better extensibility from the version you have in 3.0 alpha1. Using reflector and looking around in the binaries it comes out that to extend that provider you have to register your extension methods calling the methods of the NHibernate.Linq.Functions.FunctionRegistry class. But in all honesty I think that the way it works in alpha2 is way more elegant and it follows better the standard approach NHibernate have when it comes to configure its components.
So if you have to extend the Linq provider forget of alpha1 and compile your own version of NHibernate getting it from the Trunk.
Back to the job now: following Fabio’s instructions (and looking at the code) I came out with these classes:
public class ExtendedEqualsGenerator : BaseHqlGeneratorForMethod { public ExtendedEqualsGenerator() { // the methods call are used only to get info about the signature, the actual parameter is just ignored SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<Byte>(x => x.Equals((Byte)0)), ReflectionHelper.GetMethodDefinition<SByte>(x => x.Equals((SByte)0)), ReflectionHelper.GetMethodDefinition<Int16>(x => x.Equals((Int16)0)), ReflectionHelper.GetMethodDefinition<Int32>(x => x.Equals((Int32)0)), ReflectionHelper.GetMethodDefinition<Int64>(x => x.Equals((Int64)0)), ReflectionHelper.GetMethodDefinition<UInt16>(x => x.Equals((UInt16)0)), ReflectionHelper.GetMethodDefinition<UInt32>(x => x.Equals((UInt32)0)), ReflectionHelper.GetMethodDefinition<UInt64>(x => x.Equals((UInt64)0)), ReflectionHelper.GetMethodDefinition<Single>(x => x.Equals((Single)0)), ReflectionHelper.GetMethodDefinition<Double>(x => x.Equals((Double)0)), ReflectionHelper.GetMethodDefinition<Boolean>(x => x.Equals(true)), ReflectionHelper.GetMethodDefinition<Char>(x => x.Equals((Char)0)), ReflectionHelper.GetMethodDefinition<Decimal>(x => x.Equals((Decimal)0)), ReflectionHelper.GetMethodDefinition<Guid>(x => x.Equals(Guid.Empty)), }; }