Sunday, May 13, 2007
Sunday, May 13, 2007 5:31:44 PM (SE Asia Standard Time, UTC+07:00) (Enterprise)

I wrote earlier about my experiences using the Application Block Software Factory to create a new Application Block and Provider - it started well - and creating my first provider went fine.

Putting things into production was a slightly different matter.

Again the docs are thin - and it took a brief email exchange between myself, Tom Hollander and Fernando Simonazzi of Clarius Consulting to solve one problem I came unstuck with (no doubt attributed mainly to my first crack at ObjectBuilder and ABSF).

The problem I ran into relates to the ProviderData classes that are created by the ABSF. ProviderData classes are created for each of your providers and contain the configuration information required for your provider (read from the .config file). ABSF will also create another class in the source file for your ProviderData class - an Assembler class - ProviderAssembler. ProviderAssembler implements Object Builder's IAssembler interface and is responsible for handing back an instance of your provider, along with feeding any strongly typed settings to the constructor of your provider as required.

In broad terms - there are two ways to build classes from your application block using ObjectBuilder: IAssembler or using ObjectBuilder's generic CustomProviderAssembler method.

It's not immediately obvious that there are two provider creation strategies here or that there can be issues if you mix the two.

One is strongly typed - using your own Provider Assembler class. In this case any attributes you declare in your settings file....

<add name="Provider1" type="MyProvider, ProviderProject.Providers" databaseName="Test" specialProperty="Test" />

(databaseName and specialProperty) will be referred to in your ProviderData class as properties like the following...(just the databaseName attribute here)

private const string DATABASE_NAME = "databaseName"; [ConfigurationProperty(DATABASE_NAME)] public string DatabaseName { get { return (string)this[DATABASE_NAME]; } set { this[DATABASE_NAME] = value; } }

During the call to your assembler's Assemble method - you can pass the values of these convenient and strongly typed properties into your provider's constructor.

However here's were I came unstuck.

For each of your ProviderData classes - there is also a BaseProviderData class - and at first glance this seems like correct place to place any provider properties that may be common to all your providers - with one very important exception.

The ABSF also creates a CustomProviderData class - which ALSO derives from the BaseProviderData.

CustomProviderData doesn't implement properties for configuration - it simply reads all the attributes in your settings and places them into a property bag (a name value pair collection) which will get passed into the constructor of your implemented CustomProvider. You then retrieve the settings from the NVC as you need them in your provider (casting into the required types for each attribute).

So...

<add name="Provider2" type="MyCustomProvider, ProviderProject.Providers" databaseName="Test" setting1="Test" setting2="Test" />

In this case setting1, and setting2 will appear in the NVC when received by MyCustomProvider's constructor - BUT - if the databaseName property was defined in the BaseProviderData class - it will NOT be included in the NVC. The NVC is built for 'unknown' attributes only and in the pattern of assembly provided in the ABSF - databaseName is now a 'known' configuration property (known by the BaseProviderData class) and so won't be included.

So - if you are considering offering the client the option to create their own custom providers (as opposed to pre-defined strongly typed providers in the block) - be very careful about placing common property settings in the BaseProviderData class - because if a custom provider needs an attribute of the same name - it will never see it since it won't be included in the NVC of settings during construction.



| Comments [0] | | #  
Thursday, May 10, 2007
Thursday, May 10, 2007 7:38:07 AM (SE Asia Standard Time, UTC+07:00) (Books)

I've been reading Charles' book, Appplications = Code + Markup, and spotted the flame posted by Jeff Atwood - How Not To Write a Technical Book (which I think was a bit thin all-round as a posting) where he compares Charles' book to Adam Nathan's Windows Presentation Foundation Unleashed.

Charles Petzold's book may lack a little color and design - but he's a skilled software developer and a very thoughtful author. Every code example comes with a matching source and .sln file (there are over 150 short and helpful code projects).

Charles also thought carefully about the division of the book into two halves - code and then markup - and I find it helps enormously to focus on code first - which in turn gave me a deeper understanding of what was going on in the XAML markup that followed. On Charles' own site he says openly that he wishes the design had included more screen shots - but his book is already a 976 page tour de force and frankly I'm glad it was kept as lean and clean as it is.

That said when ever I've really wanted to get a solid understanding of any topic I've usually read more than just one book - and so seeing two great books out there in two different styles can only be a good thing.



| Comments [0] | | #  
Wednesday, May 09, 2007
Wednesday, May 09, 2007 4:37:51 PM (SE Asia Standard Time, UTC+07:00) (ASP.Net)

aspnet_merge.exe exited with code 1 - read on...

There are a few good articles around that describe the differences between the default Web project in VS2005, and Web Application Projects (which are included with SP1 now). Having come from custom scripts using XCOPY in VS 2003 - I was comfortable with the Web Application Project model - knowing that the site would be compiled into a single DLL which along with all the required files to run the site - could just be copied/XCOPYd/FTPd into production.

I also think the loose directory structure and compilation options of the standard Web Project in VS2005 are pretty cool too. That said for a lot of Web applications - I think the Web Application Project makes a lot of sense.

Rick Strahl has written a pretty good summary of the issues and differences between the default Web Project and Web Application Project formats - at Web Application Projects and Web Deployment Projects are here

We recently switched back to a Web Application Project on one project - but wanted to keep the Web Deployment Project - since the compiler options, pre and post build command options (in the source project file) were a convenient place to perform configuration specific tasks in a build.

For one site in particular we wanted to be able to publish new binaries quickly if needed and so the Web Deployment options were set to 'Merge all outputs to a single assembly', and 'Treat as libaray component'.

I chose the default namespace for the Web Application Project as the assembly name to merge to in the Web Deployment Project.

And at that point I was stuck - the build failed with am  '"aspnet_merge.exe" exited with code 1' failure message.

I enabled Detailed MSBuild messages in the Output window - (Tools, Options, Projects and Solutions, Build and Run - bottom combo box) and saw the following message the next time I tried to build.

The target assembly 'DCL.MG.Web' lists itself as an external reference.

After some experimenting - I told the Web Deployment Project to build to an assembly with a different name - in this case "DCL.MG.Website" - and I discovered two assemblies in the output directory.  One called DCL.MG.Web.dll (from my Web Application Project) and one called DCL.MG.Website.dll which the Web Deployment Project had created.

Using IL DASM - I could see that the DCL.MG.Website assembly had only two classes in it - an ApplicationBrowserCapibilitiesFactory and global_asax. The rest of the site had compiled into the DCL.MG.Web assembly fine.

I can live with this extra assembly - it's small and uploads fine with the other binaries when we do an update. I'm just a little curious as to why this is happening - why we're not getting a single assembly, and whether anyone else has discovered this as well.



| Comments [0] | | #  
Monday, May 07, 2007
Monday, May 07, 2007 6:54:30 PM (SE Asia Standard Time, UTC+07:00) (C#)

Back in March I went to the MSDN Roadshow in London to see presentations on several topics - one of them was LINQ.

In my attempts to keep up with the avalanche of software coming out of Microsoft - I have a short list of beefy books to read, weblogs to keep up with, and videos and Webcasts to watch.

The presentation at the roadshow in March was ok - but I thought for a while about the cost of attending; the time it took to get there - the structured format of the show and my never ending need for utilitarian sources of good information.

Today I came across Mike Champion's very helpful post...

Accelerating Evolution: LINQ News from Mix 2007 which includes a link to a video of Anders' presentation at Mix 2007 .

Anders' presentation is brilliant; fluid and clear - and really demonstrates the LINQ language enhancements well.

What's more I was able to watch it at a time of my choosing, and at my own pace - which makes me wonder a little about the real benefit of the Roadshows (apart from the less than subtle injection of a lot of MS Office 2007 mini-marketing presentations between each of the main items of the event).

Mix 07 on the other hand is a 'whole-n-other' thing.... :-)



| Comments [0] | | #