CA1502:AvoidExcessiveComplexity and Lambdas

[Source: http://geekswithblogs.net/EltonStoneman]

In code with lots of lambda expressions, you may trigger a false positive for the Code Analysis rule CA1502 “AvoidExcessiveComplexity”. The rule calculates cyclomatic complexity using the logic in Microsoft.FxCop.Sdk.MethodMetrics, which enumerates the instruction set and increments complexity count when it finds one of a given set of opcodes.

The rule was triggered code which uses the Fluent DAL approach to populate a composite entity:

public static Entity GetEntity(int entityId)

{

//populate basic details:

Entity entity = Fluently.Load<Entity>().With<EntityMap>()

.From<GetEntity>(i => i.Id = entityId,

x => x.Execute());

//load child entities:

if (entity.IsKnown)

{

entity.Address = Fluently.Load<Address>().With<AddressMap>()

.From<GetEntityAddresses>(i => i.Id = entityId,

x => x.Execute());

entity.Contact = Fluently.Load<Contact>().With<ContactMap>()

.From<GetEntityContacts>(i => i.Id = entityId,

x => x.Execute());

}

else

{

//more of the same

The method in question had a single if/else branch, no other conditional logic, but 7 fluent calls totalling 12 lambdas. I calculate the cyclomatic complexity to be 2, and NDepend agrees. FxCop tells me the complexity is 26.

I stripped this down to a much simpler sample and found the same issue:

public void CCCheck2()

{

Fluently.Load().With().From(i => i.ToString(), x => x.ToString());

Fluently.Load().With().From(i => i.ToString(), x => x.ToString());

Fluently.Load().With().From(i => i.ToString(), x => x.ToString());

}

– this gives a CC of 13, although it has no conditional logic at all.

The answer’s in the IL – the lambdas are emitted as private static classes and executed using an instance which is lazy-loaded:

IL_000b: ldsfld class [System.Core]System.Func`2<int32,string> FxCopCC.LambdaSample::’CS$<>9__CachedAnonymousMethodDelegate6′

IL_0010: brtrue.s IL_0025

IL_0012: ldnull

IL_0013: ldftn string FxCopCC.LambdaSample::'<CCCheck>b__0′(int32)

IL_0019: newobj instance void class [System.Core]System.Func`2<int32,string>::.ctor(object,

native int)

IL_001e: stsfld class [System.Core]System.Func`2<int32,string> FxCopCC.LambdaSample::’CS$<>9__CachedAnonymousMethodDelegate6′

IL_0023: br.s IL_0025

br and brtrue are transfer of control statements, so every lambda expression actually causes a branch – where the IL checks to see if there’s a cached instance of the delegate, or whether it needs to instantiate one – and a return. The complexity rating is correct for the IL, as 1 + 2x(number of lambdas).

But cyclomatic complexity is a measure of readability, so the additional branches in the IL should be irrelevant. The short term solution is to suppress the message on methods with heavy lambda usage. A longer term option is an alternative rule which uses a different calculation.

A side point is that the IL isn’t aggressively optimised by the compiler – lambdas with identical code are generated as separate private classes, each with their own lazy-loading check, so to avoid that overhead lambdas which are reused can be centralised:

private Func<int, string> GetInitialise()

{

return new Func<int,string>(i => i.ToString());

}

Tip/Trick: Increase your VS screen real estate by disabling HTML Navigation Bar

Tip/Trick: Increase your VS screen real estate by disabling HTML Navigation Bar

Below is a tip/trick I twittered via my Twitter account earlier today.  A number of people seemed interested in – so I thought i’d blog it here too.

HTML Navigation Bar in VS 2008

By default, when you are in HTML source-editing mode with VS 2008 and Visual Web Developer 2008 Express edition there is a set of drop-downs that are rendered immediately above the HTML text editor view:

step1

This set of drop-downs is called the "Navigation Bar", and in the VS 2008 HTML editor they allow you to navigate between functions and methods defined within the HTML.  These include both JavaScript client-side functions defined inline within the .aspx/.html file, and server-side methods defined in-line within the .aspx file when in single-file mode (meaning no code-behind file).

Disabling the HTML Navigation Bar and Getting back some pixels

Personally I don’t find the HTML navigation bar super useful – since I tend not to define JavaScript functions inline within the HTML (instead I use more unobtrusive JavaScript techniques and put my JavaScript code in separate files), and I usually use code-behind instead of single-file event handlers for server-side code.

If you are like me and also don’t find yourself using that particular navigation toolbar much, you’ll be happy to know that you can turn it off in VS 2008 and get back about 40-50 pixels that can instead be applied toward your HTML source code view.  To-do this, just select the Tools->Options menu item within VS, navigate to the "Text Editor->HTML" node and uncheck the "Navigation Bar" checkbox option:

step2

Once you do this and press the "ok" button, you’ll find that the drop-downs are gone and you have more screen real estate:

step3

(Note: if there is no immediate change after you hit ok, try closing and then re-opening the HTML/ASP.NET file)

Hope this helps,

Scott

P.S. By default with VS 2010 (starting with Beta2) we are hiding the navigation bar when in HTML mode with the standard web profile – you can then turn it back on via Tools->Options if you find it useful.  VS 2010 also has a new optional "code optimized" web profile as well that turns off all toolbars, dropdown and HTML designers.

Improving WebService Security Guide on CodePlex

Hi folks, came across a great article that talks about WebServices(WCF Services) and
Security.

The most common starting point in improving security, is to use TLS (Transport
Layer Security of which SSL is a subset). I once spent 9 months working out digital
signatures and passing several documents through out of band of envelopeslong story.

There’s a whole bunch of How-To’s also – very good!

With over 26000 downloads since August 1, I think this is a much needed area.
Well done guys – big congrats for your efforts.

Enjoy –

http://wcfsecurityguide.codeplex.com/

—- snip —-

patterns
& practices Improving Web Services Security – Now Released

Welcome to the patterns & practices Improving Web Services Security: Scenarios
and Implementation Guidance for WCF
project site! This guide shows you how to
make the most of WCF (Windows Communication Foundation). With end-to-end application
scenarios, it shows you how to design and implement authentication and authorization
in WCF. Learn how to improve the security of your WCF services through prescriptive
guidance including guidelines, Q&A, practices at a glance, and step-by-step how
tos. It’s a collaborative effort between patterns & practices, WCF team members,
and industry experts. This guide is related to our WCF
Security Guidance Project
.

Parts

Part I, “Security Fundamentals for Web Services”
Part II, “Fundamentals of WCF Security”
Part III, “Intranet Application Scenarios”
Part IV, “Internet Application Scenarios”

Forewords
  • Foreword
    By Nicholas Allen

  • Foreword
    By Rockford Lhotka
Chapters
  • Introduction

  • Solutions
    at a Glance

  • Fast
    Track – A Guide for Getting Started
Part I, Security Fundamentals for Web Services
  • Ch
    01 – Security Fundamentals for Web Services

  • Ch
    02 – Threats and Countermeasures for Web Services

  • Ch
    03 – Security Design Guidelines for Web Services
Part II, Fundamentals of WCF Security
  • Ch
    04 – WCF Security Fundamentals

  • Ch
    05 – Authentication, Authorization and Identities in WCF

  • Ch
    06 – Impersonation and Delegation in WCF

  • Ch
    07 – Message and Transport Security in WCF

  • Ch
    08 – WCF Bindings Fundamentals
Part III – Intranet Application Scenarios
  • Ch
    09 – Intranet – Web to Remote WCF Using Transport Security (Original Caller, TCP)

  • Ch
    10 – Intranet – Web to Remote WCF Using Transport Security (Trusted Subsystem,HTTP)

  • Ch
    11 – Intranet – Web to Remote WCF Using Transport Security (Trusted Subsystem TCP)

  • Ch
    12 – Intranet – Windows Forms to Remote WCF Using Transport Security (Original Caller,
    TCP)
Part IV – Internet Application Scenarios
  • Ch
    13 – Internet – WCF and ASMX Client to Remote WCF Using Transport Security (Trusted
    Subsystem, HTTP)

  • Ch
    14 – Internet – Web to Remote WCF Using Transport Security (Trusted Subsystem, TCP)

  • Ch
    15 – Internet – Windows Forms Client to Remote WCF Using Message Security (Original
    Caller, HTTP)

Checklist

  • WCF
    Security Checklist

“Failed to create BizTalk Project” in VS 2008 (BTS 2009)

Like me you may have received this lately – it was all working before (and especially
on the developers machine 🙂 .

It turns out the VS2008 loves to update a registry key post installation, any sort
of new VS.NET version, e.g. VS.NET Test tools etc, will overwrite this key.

BTS specific information is wiped away..fortunately we set the registry key back
as follows:

http://blogs.msdn.com/biztalkcrt/archive/2009/08/21/visual-studio-2008-fails-to-create-open-biztalk-projects.aspx

(x86 and x64 scenarios)

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Projects\{FAE04EC0-301F-11d3-BF4B-00C04F79EFBC}]

“PossibleProjectExtensions”=”csproj”   – Original VS install reg value.
“PossibleProjectExtensions”=”csproj;btproj” – Post Biztalk installation reg value

BizTalk Server 2009 Unleashed

Hi all

I am REALLY excited to announce, that I will be co-authoring a book on BizTalk. I
will be a part of a terrific team consisting of

  • Anush Kumar
  • Brian Loesgen
  • Charles Young
  • Jon Flanders
  • Scot Colestock
  • Tom Canter
  • Me 🙂

Together we will be writing “BizTalk Server 2009 Unleashed”, which is so new, that
you cannot find it on the web page of the publisher or any other sites. It is so new,
that we haven’t even signed our contracts with the publisher yet, which may cause
someone to quit the project if they are not happy about the contract so nothing promised
yet.

But, needless to say, I am really excited, and giving the team, also feeling quite
humble :-).

This will be my first book.

Wohooo



eliasen

It’s been a while

Hi all

So, sorry to see it, but it appears it has been almost two months since my last blog
post – hope to get back on track soon.

Since the last time, I have installed Windows 7 RTM on my laptop, and one of the reasons
I haven’t blogged is, that I couldn’t get Windows
Live Writer Backup to restore my backup of Windows Live Writer from my old Windows
XP installation. That turned out to be a silly thing For others; You cannot restore
using WLW Backup without having run Windows Live Writer first. It isn’t enough to
install it, it must have been run also. Oh well.

 

I hope to entertain you all some more from now on

 



eliasen

Retrieving multiple item names based on lots of item numbers

Hi all

Some weeks ago, I had a customer that had an Order XML and needed to fetch all the
names of the ordered items based on the item number that was in the XML.

He contacted me because the solution he had thought of didn’t work. What he did was
that he mapped the Order XML to a SQL Adapter schema that called an SP in SQL Server
to get the item name based on the item number. The issue he ran into was, that the
SP got called multiple times – once for each item, and the SQL adapter didn’t seem
to batch all the results into one result for his orchestration.

So, given this simplified Order:

<ns0:Order xmlns:ns0="http://MultipleCallsToSP.Order">

  <Header>

    <CustomerName>CustomerName_0</CustomerName>

    <OrderNumber>OrderNumber_0</OrderNumber>

  </Header>

  <OrderLines>

    <OrderLine>

      <ItemNumber>21</ItemNumber>

      <Quantity>42</Quantity>

    </OrderLine>

    <OrderLine>

      <ItemNumber>42</ItemNumber>

      <Quantity>21</Quantity>

    </OrderLine>

  </OrderLines>

</ns0:Order>

He mapped it to this XML:

<ns0:GetItemNameRequest xmlns:ns0="http://eliasen.dk">

  <ns0:GetItemName ItemID="21" />

  <ns0:GetItemName ItemID="42" /> 

</ns0:GetItemNameRequest>

This was then sent to SQL Server using the SQL Adapter to call a SP named “GetItemName”
which just takes an ItemID (int) as parameter and returns the ItemName hat matches
the ItemID.

Now, the schema that is generated for the SQL Server request actually doesn’t allow
for multiple GetItemName elements to be created, but that is changeable 🙂 If you
set it to have maxOcurs = unbounded, then it can occur multiple times, and what happens
is that the SP is called multiple times. Unfortunately, only one of the ItemNames
is returned – the rest is ignored.

So the customer came to me because naturally, he needed all the ItemNames and not
just one of them. I have suggested 5 possible solutions, which I will describe here.

First option

Use the pattern described at http://blog.eliasen.dk/2006/11/05/LoopingAroundElementsOfAMessage.aspx to
loop around the order lines and build the resulting XML one order line at a time.

Second option

Use enveloping in the receive location in order to get one orchestration
started for each order line.

Third option

Use the Database Lookup functoid to retrieve the ItemName based on the ItemID

Fourth option

Generate a comma separated list of ItemID’s in the map, and let the stored procedure
use that list to return the relevant ItemNames. This has some consequences for the
stored procedure. Before it looked like this:

SELECT ItemNumber, ItemName

FROM Items

WHERE Items.ItemNumber = @ItemID

FOR XML AUTO, ELEMENTS

Now, it looks like this:

SELECT ItemNumber, ItemName

FROM Items

WHERE EXISTS (select * from dbo.Split(’,’,@items) where [Items].ItemNumber = ID)

FOR XML AUTO, ELEMENTS

@items is the parameter for the SP, which is just an nvarchar that is to contain the
comma separated list.

For this to work you need the Split function, which looks like this:

CREATE FUNCTION [dbo].[Split] (@sep char(1), @s varchar(512))

RETURNS table

AS

RETURN

(    

               
WITH Pieces(pn, start, stop) AS (

                     
SELECT 1, 1, CHARINDEX(@sep, @s)

                     
UNION ALL      

                     
SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)      

                     
FROM Pieces      

                     
WHERE stop > 0    

                
)

                
SELECT pn, CONVERT(int, SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start
ELSE 512 END)) AS ID

FROM Pieces

)

In order to generate the comma separated list in your map, I have written two blog
posts about this issue, which you can find at http://blog.eliasen.dk/2009/06/22/HandlingCommaSeparatedValuesInsideAMapPartI.aspx and http://blog.eliasen.dk/2009/06/27/HandlingCommaSeparatedValuesInsideAMapPartII.aspx

Fifth option

The fifth and last option i want to mention is, that with the new SQL Server
LOB adapter from Adapter Pack 2.0, it appears that you can do it like the customer
wanted to do it in the first place with sending one XML to SQL Server and getting
an accumulated response back from SQL Server based on several calls to a stored procedure.
I haven’t had time to test this, but look out for another blog post about this 🙂

 

Hope this helps someone.

 



eliasen