Rory Primrose

I don't have a solution but I admire the problem

Recent Posts

Tags

Community

Email Notifications

Archives

Visual Studio Addin - No such interface supported

I'm working on a new Visual Studio addin that launches a profiling application that in turn runs unit and load tests. I can't recall how I created the project, but it must not have been by using the addin wizard. When I debugged the addin in another instance of Visual Studio, I got an error indicating that the addin couldn't be loaded or threw an exception. The additional information it gave was "No such interface supported".

After pulling my hair out for quite a while, the answer was that the AssemblyInfo.cs contained the following:

// Setting ComVisible to false makes the types in this assembly not visible

// to COM components.  If you need to access a type in this assembly from

// COM, set the ComVisible attribute to true on that type.

[assembly: ComVisible(false)]

Visual Studio is written mostly in the COM world, including the functionality that resolves and loads addins. This attribute hides the addin from Visual Studio. It therefore can't find the interface it is expecting when it attempts to load the addin from the configured type information. Removing this attribute from AssemblyInfo.cs (it is included by default) or setting its value to true will allow Visual Studio to correctly load the addin.

Neovolve ReSharper Plugins 1.0 released

I have just released the ReSharper Plugins 1.0 in my NeovolveX extensibility project on CodePlex. This plugin formats code as part of the ReSharper code format profiles.

The following is a copy of the Using ReSharper Plugins 1.0 documentation on the project site

Value Type Alias Formatter

The ReSharper Plugins project currently contains a single plugin that provides C# code formatting functionality. This formatting function allows for type declarations to be formatted between their alias type and their CLR type. For example, depending of the format settings defined in a code cleanup profile, bool can be converted to Boolean or Boolean converted to bool.

Configuration

The following displays the normal code format profile dialog.

ProfileSettings.jpg

When the plugin is installed, the code format profile dialog will include an additional format option called Type alias conversion.

CustomFormatProfile.jpg

The type conversion options are:
  • Do not change - No change is made to the code
  • Convert to alias type - References of CLR types are converted to their alias types (Boolean to bool for example)
  • Convert from alias type - References of alias types are converted to their CLR types (bool to Boolean for example)
The Do not change setting is the default value.

Type mappings

The following are the type mappings that are supported for converting types between alias types and their CLR types.

Alias type CLR type
object Object
char Char
string String
bool Boolean
byte Byte
short Int16
int Int32
long Int64
ushort UInt16
uint UInt32
ulong UInt64
double Double
decimal Decimal
float Single
sbyte SByte

Code examples

Code formatted to use alias types

AliasCode.jpg

Code formatted to use CLR types

CLRTypeCode.jpg

Grab it from here.

Reflection Pop Quiz - Does interface inheritance exist?

I've written some code that reflections MethodInfo objects from a type using its name and signature. This has been working well and all unit tests have passed, until now.

Consider the following code:

    internal interface IBaseInterface

    {

        void GetSomething();

    }

 

    internal interface IDerivedInterface : IBaseInterface

    {

        void DoSomethingElse();

    }

Does interface inheritance exist?

Much to my amazement, the answer is no, at least according to reflection. This is completely not what I had assumed.

Does it matter? Normally, probably not. The reason is that most people are dealing with concrete types. As concrete types provide implementations of the methods that are defined by their interfaces, the type correctly returns the expected MethodInfo objects from Type.GetMethods().

Interfaces behave very differently. If you call Type.GetMethods() on IDerivedInterface then you will be missing the methods defined in IBaseInterface. I expected that IDerivedInterface had a base type of IBaseInterface and inherited its methods. I made this assumption because that is the affect that IDerivedInterface has on types that implement it. There is an inheritance behaviour as the concrete type must implement methods for both interfaces.

What is interesting is that IDerivedInterface doesn't have a base type, and Type.GetMethods() doesn't return IBaseInterface methods. IDerivedInterface does however indicate that it implements the IBaseInterface interface.

Now things get a little curly here. An interface that implements an interface doesn't need to provide any implementation (it can't, its an interface) or do anything to satisfy implementing the interface. This makes me think that interfaces neither implement other interfaces, or inherit from them.

Here is the complete source:

using System;

using System.Reflection;

 

namespace ConsoleApplication1

{

    internal class Program

    {

        private static void Main(String[] args)

        {

            // _______________________________________________________

            //

            // Base Interface test

            // _______________________________________________________

            Type baseInterfaceTest = typeof(IBaseInterface);

 

            // This returns 1 method

            MethodInfo[] baseInterfaceMethods = baseInterfaceTest.GetMethods();

 

            // This returns false

            Boolean baseInterfaceHasBaseClass = baseInterfaceTest.BaseType != null;

 

            // This returns null

            Type[] baseInterfaceInterfaces = baseInterfaceTest.GetInterfaces();

 

            // _______________________________________________________

            //

            // Derived Interface test

            // _______________________________________________________

 

            Type derivedInterfaceTest = typeof(IDerivedInterface);

 

            // This will only return 1 method

            MethodInfo[] derivedInterfaceMethods = derivedInterfaceTest.GetMethods();

 

            // This returns false

            Boolean derivedInterfaceHasBaseClass = derivedInterfaceTest.BaseType != null;

 

            // This returns 1 interface type

            Type[] derivedInterfaceInterfaces = derivedInterfaceTest.GetInterfaces();

 

            // _______________________________________________________

            //

            // Derived Type test

            // _______________________________________________________

 

            Type derivedTypeTest = typeof(DerivedType);

 

            // This will return 2 methods (in addition to the 4 from System.Object)

            MethodInfo[] derivedTypeMethods = derivedTypeTest.GetMethods();

 

            // This will return true (System.Object)

            Boolean derivedTypeHasBaseClass = derivedTypeTest.BaseType != null;

 

            // This returns 2 interface type

            Type[] derivedTypeInterfaces = derivedTypeTest.GetInterfaces();

        }

    }

 

    internal interface IBaseInterface

    {

        void GetSomething();

    }

 

    internal interface IDerivedInterface : IBaseInterface

    {

        void DoSomethingElse();

    }

 

    internal class DerivedType : IDerivedInterface

    {

        public void DoSomethingElse()

        {

        }

 

        public void GetSomething()

        {

        }

    }

}

Posted: Jul 03 2008, 02:43 PM by Rory Primrose | with no comments
Filed under:
Changing TFS changeset comments

I had a bit of a slipup yesterday. I had a set of changes that I was relating to two different work items. I realised that I really should split up the check-in into two check-ins so that the code files are better related to their work items. What I didn't do before checking in both changesets was updating the comments of the check-ins before I committed them.

After realising my mistake, I wondered if I could change the comment of a changeset. Thankfully the answer is yes. After finding the changesets by looking at the history in TFS, I was able to simply adjust the comment to be more appropriate to the changeset and click Save. Simple.

Posted: Jul 03 2008, 09:53 AM by Rory Primrose | with no comments
Filed under: ,
foreach vs for

I've just hit the foreach code coverage issue again in one of my unit tests (see my Code coverage doesn't like foreach loops post). To ensure that my tests were correctly covering all possibilities, I had to change the foreach loop into a for loop and run the test again.

The issue in this case is that the collection object I was referencing was ConfigurationElementCollection which implements ICollection. Unfortunately, this type doesn't expose an indexer property. In order to test the code coverage metrics using a for loop, I first had to create an array of the appropriate length and copy across the items across.

After running the test again, I had 100% code coverage. I have now confirmed that the missing blocks in coverage are a result of the foreach statement rather than an issue with my unit test. Now the question is do I remove the additional code and redundant array copy ? The reasons to convert the code back to the foreach loop are:

  • Cleaner code
    • Less bloat
    • More understandable
  • Code coverage shouldn't define coding style

The second point is guaranteed to get some people in a flap. To be clear, I am not saying that testability shouldn't have a bearing on coding style, I'm saying that code coverage shouldn't define coding style. While this post is about code coverage, I should also point out that code coverage doesn't really mean much by itself. It is just an indicator.

In this case, the unit tests were valid and covered all the angles, so the question is purely whether a code coverage metric is important enough to modify the code.

Another thing also comes to mind. What about performance? By using the array, I have the additional overhead of creating an array and populating it from the ICollection, but then I have the performance gain from not using the IEnumerator invoked by the foreach statement.

A quick test gave me a suitable answer.

using System;

using System.Collections.ObjectModel;

using System.Diagnostics;

using System.Threading;

 

namespace ConsoleApplication1

{

    internal class Program

    {

        private static void Main(String[] args)

        {

            Collection<String> items = new Collection<String>();

 

            for (Int32 index = 0; index < 10; index++)

            {

                items.Add(Guid.NewGuid().ToString());

            }

 

            Stopwatch watch = new Stopwatch();

            const Int32 Iterations = 10000;

 

            Thread.Sleep(1000);

 

            watch.Start();

 

            for (Int32 index = 0; index < Iterations; index++)

            {

                foreach (String item in items)

                {

                    Debug.WriteLine(item);

                }

            }

 

            watch.Stop();

 

            Console.WriteLine("foreach took {0} ticks", watch.ElapsedTicks);

 

            watch.Reset();

            watch.Start();

 

            for (Int32 index = 0; index < Iterations; index++)

            {

                String[] newItems = new String[items.Count];

 

                items.CopyTo(newItems, 0);

 

                for (Int32 count = 0; count < newItems.Length; count++)

                {

                    Debug.WriteLine(newItems[count]);

                }

            }

 

            watch.Stop();

 

            Console.WriteLine("for took {0} ticks", watch.ElapsedTicks);

 

            Console.ReadKey();

        }

    }

}

Each time I run this test, the for loop runs at 70% of the time of the foreach loop, even with the array copy.

While code coverage by itself is not enough to make me change my coding style, a performance improvement and more accurate code coverage is a good enough reason.

Posted: Jul 02 2008, 10:31 AM by Rory Primrose | with no comments
Filed under:
Installing WiX 3.0 - Votive on Vista x64

Here's a tip for young players. You may find that getting the latest WiX 3.0 beta from here gives you an error saying that you need to have a version of Visual Studio installed that is above the Express edition. I have Team Suite installed, so it should be a problem. After lots of research, I came across this post which gave me the answer. It wasn't a problem with the version of Visual Studio that I had installed, it was because latest build published on the SourceForge download page was prior to their support of x64 systems. After downloading the latest build published here, it's all good.

Posted: Jun 27 2008, 11:36 AM by Rory Primrose | with no comments
Filed under: ,
Readonly is in the eye of the beholder

One of my most used feature in the 3.5 compiler for .Net is automatic properties. In case you are not familiar, here is a recap.

Traditionally, properties work with a backing field. For example:

    private String _someValue;

 

    public String SomeValue

    {

        get

        {

            return _someValue;

        }

        set

        {

            _someValue = value;

        }

    }

Automatic properties under the 3.5 compiler allow this code to be represented as:

    public String SomeValue

    {

        get;

        set;

    }

Automatic properties make code cleaner and easier to use. Additionally, they also require less testing. There isn't any point testing their logic of accessing the backing field to ensure correct operation and they appear with 100% code coverage. My biggest gripe though is that they don't truly support readonly definitions.

The documentation on MSDN says:

Auto-implemented properties must declare both a get and a set accessor. To create a readonly auto-implemented property, give it a private set accessor.

The implementation of automatic properties by the compiler define that readonly automatic properties are achieved by assigning a private scope to the set accessor. For example:

    public String SomeValue

    {

        get;

        private set;

    }

Unfortunately, I think this is a cheap bandaid hack. It doesn't make the property truly readonly. It is technically readonly, but only from the perspective of external callers. Internal to the class, the property is not readonly because the private scope makes setting the property value possible. This doesn't protect the value of the backing field which is what a true readonly property should be able to support. See here for the MSDN documentation on the readonly keyword.

I would like to see this changed. Without understanding the complexities of writing compilers, I would think that this change would not be too significant. The simple fix would be to enhance the syntax of the automatic property setter definition. If the private set statement could be enhanced to understand a readonly keyword, then the compile could mark the backing field with the same readonly keyword. For example:

    public String SomeValue

    {

        get;

        private readonly set;

    }

This would then be interpreted by the compiler as something like this:

    private readonly String _someValue;

 

    public String SomeValue

    {

        get

        {

            return _someValue;

        }

        set

        {

            _someValue = value;

        }

    }

I have added this as a suggestion to Microsoft Connect here.

Posted: Jun 26 2008, 11:11 AM by Rory Primrose | with 2 comment(s)
Filed under:
Load tests don't like code coverage

I have been pulling my hair out this afternoon trying to figure out why my code is performing so badly in a load test. After playing with the code and running a lot of tests, I didn't have any answers until I looked at my testrunconfig file. Code coverage was the first thing I looked at.

With code coverage turned on, the report looked like this.

 

After I turned code coverage off, I was much happier.

The Test Response Time graphs (top right) highlight the difference between the test run performance as does the the CPU usage (red line in the bottom right graph). Of the four tests, the one that is doing the most work was averaging 6.76 seconds per test with code coverage which is atrocious. Without code coverage, this test was running an average of 0.00024 seconds per test. Just a little different.

Updated: Changed images so they are more readable and changed the scale of the Test Response Time graph so the difference of the tests can be seen.

Posted: Jun 02 2008, 04:13 PM by Rory Primrose | with 2 comment(s)
Filed under:
Readable testable code

I read Patrick Smacchia's post this morning about a simple trick to code better and to increase testability and found it to be a great argument. These are the kinds of posts that I really enjoy reading and thinking about. They often have me hacking up test projects to flesh out ideas or kicking off Reflector to see what the BCL is doing.

This was a good post because it got me to challenge why I am coding in the particular style that I have. I have always been a fan of combining if tests when it doesn't result in overly complex logic. In this case, Patrick is arguing that such a style of coding increases nesting depth and makes testing harder.

Take this test case based on his post:

using System;

using System.Collections.Generic;

using System.Diagnostics;

 

namespace ConsoleApplication1

{

    internal class Program

    {

        public static void MethodA(List<String> list)

        {

            foreach (String item in list)

            {

                if (item == null || item.Length == 0

                    || item.Contains("a"))

                {

                    continue;

                }

 

                Console.Write(String.Empty);

            }

        }

 

        public static void MethodB(List<String> list)

        {

            foreach (String item in list)

            {

                if (item == null)

                {

                    continue;

                }

 

                if (item.Length == 0)

                {

                    continue;

                }

 

                if (item.Contains("a"))

                {

                    continue;

                }

 

                Console.Write(String.Empty);

            }

        }

 

        private static void Main(String[] args)

        {

            List<String> items = new List<String>(100);

 

            for (Int32 index = 0; index < 100; index++)

            {

                items.Add(index.ToString());

            }

 

            Stopwatch watch = new Stopwatch();

 

            watch.Start();

 

            for (Int32 firstLoop = 0; firstLoop < 100000; firstLoop ++)

            {

                MethodA(items);

            }

 

            watch.Stop();

 

            Int64 firstTickCount = watch.ElapsedTicks;

 

            watch.Reset();

 

            watch.Start();

 

            for (Int32 secondLoop = 0; secondLoop < 100000; secondLoop++)

            {

                MethodB(items);

            }

 

            watch.Stop();

 

            Int64 secondTickCount = watch.ElapsedTicks;

 

            Console.WriteLine(firstTickCount);

            Console.WriteLine(secondTickCount);

            Console.WriteLine(secondTickCount - firstTickCount);

            Console.ReadKey();

        }

    }

}

MethodA contains the combined if tests while MethodB separates them out into individual tests. While I'm not sure about the nesting depth argument due to compiler optimizations, I totally agree about the increase in testability. I also think that such a coding style is much more readable. The risk of combined if tests is that they quickly become complex and difficult to understand.

The first question I had about this was what is the impact on compiled code? Does this change impact performance? After writing up the above test case, I found that it doesn't (as unscientific as the test case is). The next step was to check out the difference in the IL. Turns out that both methods have exactly the same IL. This would explain the similar performance results. I say similar because there would be many outside influences that would result in slightly different outcomes.

So performance isn't a problem as the compiler optimizes the code. The code is more readable and there is no risk of getting confused about the combination of if statements. It is also, as Patrick argues, more testable. The individual continue statements will not get covered if the related scenario of an if statement is not tested for. On this point however, Visual Studio will highlight the line as partially tested rather than 100% covered, but doesn't help in telling you which part of the statement wasn't covered. This makes this style more testable as it is completely clear what hasn't been tested.

I'm no IL expert, but it is interesting that the compiler seems to choose the more complex version (at least to Reflectors interpretation). The following is Reflectors decompilation of the release build interpreted in C#.

        public static void MethodB(List<string> list)

        {

            foreach (string item in list)

            {

                if (((item != null) && (item.Length != 0)) && !item.Contains("a"))

                {

                    Console.Write(string.Empty);

                }

            }

        }

I think I have a new change to my coding style.

Posted: Jun 02 2008, 01:14 PM by Rory Primrose | with 2 comment(s)
Filed under:
ReflectorLink 1.0 Released

I have been working on a CodePlex project over the last month or so that contains a set of extensibility tools. I have just released ReflectorLink 1.0 which is a Visual Studio addin that launches Reflector.

The following is a copy of the Using ReflectorLink 1.0 documentation on the project site.

ReflectorLink is a Visual Studio addin that launches Reflector. Before launching Reflector, it checks to see whether Reflector is already running. If it does find Reflector already running, it will set it as the active application. If Reflector is not found, it will be started (assuming it can be found). After Reflector has been activated/started, additional commands may be sent to it to load assemblies.

ReflectorLink can be invoked from the Tools menu, Solution Explorer context menus or the code document context menu.

Tools menu
Click the Tools menu and select Reflector.

ReflectorLink1-0ToolsMenu.jpg

When launching Reflector from the Tools menu, Reflector will be launched with no further action if no solution is loaded. If there is a solution loaded, the binary references of each project will be loaded into Reflector.

Code document
Right-click on a code document and select Reflector.

ReflectorLink1-0CodeDocument.jpg

When launching Reflector from the code document, ReflectorLink will determine if there is a related project that has binary references. Any references found will be loaded into Reflector.

Note: ReflectorLink does not yet support resolving items clicked in the code document. Only the related project is used to determine what to load into Reflector.

Solution Explorer
There are several scenarios where Reflector can be launched in Solution Explorer. These are:
  • Solution node
  • Project node
  • Project References node
  • Project Reference node
  • Solution Items

In each scenario, the Reflector menu item will only be enabled if binary references can be found. For solution items, the menu item will only be displayed if the solution item selected is an exe or dll file.

Solution node
Right-click on the solution node and select Reflector.

ReflectorLink1-0SolutionNode.jpg

When launching Reflector from a solution node, ReflectorLink will determine the set of binary references for each project in the solution. Any references found will be loaded into Reflector.

Project node
Right-click on a project node and select Reflector.

ReflectorLink1-0ProjectNode.jpg

When launching Reflector from a project node, ReflectorLink will determine the set of binary references for the project. Any references found will be loaded into Reflector.

Project References node
Right-click on the References node in a project and select Reflector.

ReflectorLink1-0ReferencesNode.jpg

When launching Reflector from a References node, ReflectorLink will determine the set of binary references for the related project. Any references found will be loaded into Reflector.

Project Reference node
Right-click on a reference node in a project and select Reflector.

ReflectorLink1-0ReferenceNode.jpg

When launching Reflector from a reference node, ReflectorLink will determine whether the reference is a binary reference or a project reference. The menu item will be enabled if the reference is a binary reference and will load it into Reflector when launched.

ReflectorLink1-0ReferenceNodeDisabled.jpg

If the reference is a project reference, the menu item will be disabled.

Solution Item node
Right-click on a solution item node that is an exe or dll and select Reflector.

ReflectorLink1-0SolutionItem.jpg

When launching Reflector from a solution item node, ReflectorLink will determine whether the item is an exe or dll file. The menu item will be invisible if the item is not an exe or dll. The selected item will be loaded into Reflector when launched.

ReflectorLink 1.0 can be downloaded from here.

Finding the type of UIHierarchyItem.Object

I have written a few addins over the last couple of years and I have always found the object model really painful to deal with. One of the more common problems I have encountered is trying to identify the type of UIHierarchyItem.Object. This is especially common when you deal with the contents of the Solution Explorer window.

I only know of one solution for identifying the real type behind the object. You can make a call out to Microsoft.VisualBasic.Information.TypeName(Object) to attempt to resolve the type. This wasn't always successful and was also a little limited as the object often implements multiple types. I realised that there was a very easy and more comprehensive way of figuring out what types were being implemented.

By using this DebugHelper class in your addin solution, you will be able to figure out the object types. The Conditional attribute ensures that these methods (and calls to them) will not appear in your release build. The method takes a UIHierarchyItem and searches all the publicly available types of all the assemblies in the app domain for types that are implemented by the UIHierarchyItem.Object property.

using System;

using System.Diagnostics;

using System.Reflection;

using EnvDTE;

 

namespace Neovolve.Extensibility.VisualStudio

{

    /// <summary>

    /// The <see cref="DebugHelper"/>

    /// class is used to help with debugging tasks for Visual Studio addin development.

    /// </summary>

    /// <remarks>

    /// This class was created by Rory Primrose for the

    /// <a href="http://www.codeplex.com/NeovolveX" target="_blank">NeovolveX</a>

    /// project.

    /// </remarks>

    public static class DebugHelper

    {

        /// <summary>

        /// Identifies the internal object types.

        /// </summary>

        /// <param name="item">The item.</param>

        [Conditional("DEBUG")]

        public static void IdentifyInternalObjectTypes(UIHierarchyItem item)

        {

            if (item == null)

            {

                Debug.WriteLine("No item provided.");

 

                return;

            }

 

            if (item.Object == null)

            {

                Debug.WriteLine("No item object is available.");

 

                return;

            }

 

            // Loop through all the assemblies in the current app domain

            Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();

 

            // Loop through each assembly

            for (Int32 index = 0; index < loadedAssemblies.Length; index++)

            {

                // Assume that the assembly to check against is EnvDTE.dll

                IdentifyInternalObjectTypes(item, loadedAssemblies[index]);

            }

        }

 

        /// <summary>

        /// Identifies the internal object types.

        /// </summary>

        /// <param name="item">The item.</param>

        /// <param name="assemblyToCheck">The assembly to check.</param>

        [Conditional("DEBUG")]

        public static void IdentifyInternalObjectTypes(UIHierarchyItem item, Assembly assemblyToCheck)

        {

            // Get the types that are publically available

            Type[] exportedTypes = assemblyToCheck.GetExportedTypes();

 

            // Loop through each type

            for (Int32 index = 0; index < exportedTypes.Length; index++)

            {

                // Check if the object instance is of this type

                if (exportedTypes[index].IsInstanceOfType(item.Object))

                {

                    Debug.WriteLine(exportedTypes[index].FullName);

                }

            }

        }

    }

}

Using this debug helper method saved hours if not days in fixing this problem. I hope this helps other people as well.

When is EnvDTE.Project not an EnvDTE.Project?

When it is a EnvDTE.ProjectItem. I must admit that this one took me by surprise.

I am writing a Visual Studio addin for launching Reflector (see the CodePlex project here). You can launch Reflector from the tools menu and the Solution Explorer window and code document context menus. This issue came about when I found a bug in my addin while doing some testing. The scenario encountered was that the binary references for projects in Solution Explorer (the Project node and References node) were not resolved. I had tested this feature in another solution successfully and noticed that the difference between the solutions was that the one with the bug had the projects in solution folders.

After doing some debugging, it turns out that when a project is contained in a solution folder, the UIHierarchyItem.Object value exposed through Solution Explorer is no longer represented by an EnvDTE.Project. It is now an EnvDTE.ProjectItem. Ironically, you must reference ProjectItem.SubProject to get access to the project.

The fact that the project is a project items sub project because its parent is a folder in Solution Explorer is totally confusing.

CS2008

I have upgraded the blog to CS2008 tonight. It mostly went well, but I did waste an hour trying to get my media files to be served. Turned out that the issue was that the AppPool in IIS now needs to be run under Integrated rather than Classic. See here.

Give me the media and the Ultimate Boot CD

My dad bought a laptop that came with the typical factory image full of junk. It crashed constantly, didn't detect the anti-virus that was installed and wouldn't allow me to activate Windows Defender. It also only had the system partition for data. All good reasons for a rebuild. HP kindly don't offer media for recovery though. Not being familiar with this, I wiped the system drive for a rebuild without first burning the recovery partition to a DVD. After lots of attempts at recovery and installation, one of my actions was to set the recovery partition as the active partition so I could boot straight into it. That worked until the recovery image wanted to reboot, then I couldn't set the active partition back.

I miss the days when manufacturers would just include a couple of DVD's. Are they really that expensive to press that they can't include the disks?

Any way, Ultimate Boot CD became a lifeline.

Lying to WCF

There are cases when you need to transmit username/password credentials to WCF without transport security. The times that you should do this are rare because of the obvious security implications of sending credentials over the wire without encryption. One case where this is required is where hardware acceleration is used in a load balancer. The traffic between the load balancer and the client is encrypted, but the traffic between the load balancer and the service host is not. The issue here is that the service still needs the credentials passed to the load balancer from the client.

Drew Marsh has a great write up about how to lie to WCF about the security of the binding that it is using for a service. Nicholas Allen has also posted on the topic here and here.

More Posts Next page »