Strategy Pattern & Dependency Injection abuse.

I thought I would share in this post my thoughts on a design pattern that has changed the way I write code. The beauty is in the simplicity of this pattern. It's easy to implement and doesn't unnecessarily complicate the problem domain, in fact it simplifies it and leads you gently towards the wonderful world of Test Driven Development(TDD). The pattern is the strategy pattern.

The Strategy Pattern is also known as "Constructor injection" (or just called a "plug-ins" by those that haven't bothered reading Design Patterns).

The strategy pattern is taken to the next level by the Dependency Injection Pattern and can be implemented programmatically (or declaratively) using an IoC container. IoC (Inversion of Control) containers are powerful in the sense that all the services in your application that have access to the container have "access" to all the services that have subscribed to the container. These patterns also facilitate ... and make it easier to write tests for the services in your application by relying heavily on Interfaces.

How Dependency Injection is "abused":
The problem is that your code is no longer self documenting. You are never sure just by looking at methods where services are extracted out of the container which service they will receive from the container. This makes your code feel a little like "black magic". Extracting services from a container is also more of a performance hit than "wiring" up your services programmatically.

TDD (Test Driven Development):
This concept is about writing a programmatic test for a method/function call to ensure that the expected result is returned from the provided parameters, be it an exception, or a physical data value. Unit tests also allow for behavioural testing by recording the inner service calls expected using a Mocking Framework such as Rhino Mocks.

This can be extremely useful if you have a deep framework with multiple layers of functionality where a change in one area can have a ripple effect on other areas.

Misconceptions, and mistakes developers make with regards to TDD:
1. Writing/generating unit tests that test every single property of every object in the System. This is a waist of time and causes code bloat.
2. Unit tests are generated/written for the System AFTER the application is has been completed. This is useful, although only from a testing perspective.

The key ideas to keep in mind are:
1. What are the root or core features of my application that I need to have unit tests for. These services will normally contain the more complex code.
2. Unit tests are more useful if they are written BEFORE the system has been built. This will facilitate the design of your services and give you a deeper insight into their future extensibility requirements.
3. The unit tests serve as "specifications" for future developers that would like to use your libraries. The unit tests also provide insight into the behaviour of the API's your libraries expose.

TDD should be used to drive out the flow and design of the system you are working on. A simple example of the final result of what a set of unit tests would look like.... even before any lower level code has been written:

Snippet
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Rhino.Mocks;

namespace DemoTestProject
{

    [TestClass]
    public class MessageValidationTestFixture
    {

        private MockRepository mockRepository;

        private IDatabaseService mockDatabaseService;
        private IMetaDataExtractor mockMetaDataExtractor;
        private IFileArchiveService mockFileArchiveService;

        private static string messageContent = "Some random message";

        [TestInitialize]
        public void SetUp()
        {
            mockRepository = new MockRepository();

            mockDatabaseService = mockRepository.DynamicMock<IDatabaseService>();
            mockMetaDataExtractor = mockRepository.DynamicMock<IMetaDataExtractor>();
            mockFileArchiveService = mockRepository.DynamicMock<IFileArchiveService>();
        }

        [TestCleanup]
        public void TearDown()
        {
            mockRepository.VerifyAll();
        }

        [TestMethod]
        [DeploymentItem("TestData\\TestData.xml""TestFiles")]
        public void TestValidationSuccessfullWithCorrectMetaData()
        {
            // Record the results expected from the lower level services
            using (mockRepository.Record())
            {
                //Extract the meta data from the message content
                SetupResult.For(mockMetaDataExtractor.ExtractMetaData(messageContent)).Return(TestUtils.VALID_META_DATA);
                //Insert the message and the message data into the database and return a true(success)
                SetupResult.For(mockDatabaseService.InsertMessage(TestUtils.VALID_META_DATA, messageContent)).Return(true).IgnoreArguments();
                //Archive the message and the meta data and return the UNC path for the file
                SetupResult.For(mockFileArchiveService.ArchiveMessage(TestUtils.VALID_META_DATA, messageContent)).Return("c:\temp\archivedmessage.txt");
            }

            // Create an instance of the validator and provide mocked versions of the lower level services
            IMessageValidator validator = new MessageValidator(mockDatabaseService, mockMetaDataExtractor, mockFileArchiveService);

            // Based on the above lower level service behavior the validator should approve the message (return true)
            Assert.IsTrue(validator.ValidateMessage(TestUtils.TEST_DATA, messageContent));

        }

        [TestMethod]
        [ExpectedException(typeof(NullReferenceException))]
        [DeploymentItem("TestData\\TestData.xml""TestFiles")]
        public void TestValidationThrowsNullReferenceExceptionWithInvalidMetaData()
        {
            
            // Record the behaviour of the lower level services
            using (mockRepository.Record())
            {
                //Extract invalid data from the message
                SetupResult.For(mockMetaDataExtractor.ExtractMetaData(TestUtils.INVALID_META_DATA, messageContent)).Return(TestUtils.INVALID_META_DATA);
                // Insert the message into the database successfully
                SetupResult.For(mockDatabaseService.InsertMessage(TestUtils.INVALID_META_DATA, messageContent)).Return(true).IgnoreArguments();
                // Archive the message and the meta data
                SetupResult.For(mockFileArchiveService.ArchiveMessage(TestUtils.INVALID_META_DATA, messageContent)).Return("c:\temp\archivedmessage.txt");
            }

            //Create an instance of the validator with the lower level mocked services
            IMessageValidator validator = new MessageValidator(mockDatabaseService, mockMetaDataExtractor, mockFileArchiveService);

            //False should never be returned because a null refernce exception will be thrown before
            Assert.IsFalse(validator.ValidateMessage(TestUtils.INVALID_META_DATA, messageContent));

        }

    }
}

Interesting Finds - 22/08/2010

An easy way to deploy certificates without using a certificate store
http://www.codeproject.com/KB/WCF/wcfcertificates.aspx

Hands on labs for Enterprise library 5 (Includes some good Unity startup excersizes)
http://www.microsoft.com/downloads/en/confirmation.aspx?familyId=4f8cd377-5522-4f45-a024-44a6ca5111ec&displayLang=en

Summary of new Features in .Net 4
http://msdn.microsoft.com/en-us/library/ms171868.aspx

Overview of all the new features in WCF 4
http://msdn.microsoft.com/en-us/library/dd456789.aspx

Loads of WCF4 WF4 Samples
http://www.microsoft.com/downloads/en/confirmation.aspx?familyId=35ec8682-d5fd-4bc3-a51a-d8ad115a8792&displayLang=en

Configuration based activation in IIS and WAS
http://msdn.microsoft.com/en-us/library/ee358764.aspx

Message Security certificate
http://msdn.microsoft.com/en-us/library/ms751516.aspx

Good article on MongoDB for begginers.
http://msdn.microsoft.com/en-us/magazine/ee310029.aspx

MongoDB and linq : Rob Connery's insight
http://blog.wekeroad.com/2010/03/04/using-mongo-with-linq

Great article on WCF hosting
http://msdn.microsoft.com/en-us/library/bb332338.aspx

Thread on hosting in IIS vs using a windows Service
http://social.msdn.microsoft.com/Forums/en/wcf/thread/015d711d-ce5a-46a1-a93e-1c68746e76d3

General WCF Security information. Root location on MSDN
http://msdn.microsoft.com/en-us/library/ms732362.aspx

WCF Security Guide : A great read
http://wcfsecurityguide.codeplex.com/

Chapter 5: Authentication, Authorization, and Identities in WCF
http://msdn.microsoft.com/en-us/library/ff647503.aspx

Posted by jean with no comments
Filed under:

Deferred Custom Actions in .Net

Recently I had to implement a set of deferred custom actions within a .Net 4 Wix 3.5 environment. Getting the Deferred Custom Actions to work properly meant that I had to wrestle with all the caveats that come with using an open source deployment tool. I was a little shocked at how little documentation there is out there on the Internet with regards to .Net custom actions so I thought I would write this post.

What are Deferred Custom Actions:
These are custom actions that require elevated privileges and are run within the "Installation Script". They are custom actions that can modify the System and thus would normally require Administrator privileges. Deferred Custom Actions cannot query the standard session object that normal custom actions query but have to query the CustomActionData object. Because they are running in a different security account to the executing user they are not able to access the same memory space.

Resources:
MSDN
http://msdn.microsoft.com/en-us/library/aa368268%28v=VS.85%29.aspx

DEBUGGING CUSTOM ACTIONS
http://msdn.microsoft.com/en-us/library/aa368264%28VS.85%29.aspx

Conclusion:
The terminology is confusing to say the least and there is little or no information on Wix deferred custom actions in .Net. The Microsoft documentation doesn't really help you to implement the solution quickly when you only have 2 hours to get the job done and don't really have much understanding of the Wix DSL. It's a real shame in my opinion because Wix has a lot of potential to be an awesome .Net Deployment tool especially now that Wix 3.5 integrates with the VS 2010 IDE.... and it's free.... for now....

The version of Wix 3.5 that I am using: 1923. There are later versions of the Wix 3.5 framework that I am a little afraid to install because the default deployment locations have changed and don't seem to function properly in a 64 bit environment.

Issues that I faced that didn't seem to have any documentation:
1) Even though once you have installed Wix 3.5 and added a "C# Custom Action project" to your solution which defaults to .Net 4 within the Visual Studio 2010 environment you need to set the Target Framework back to .Net 3.5 otherwise your (deferred)custom actions will not work.
2) The Wix setup project needs to reference the Custom Action project and ALL the projects referenced by the Custom Action Project.
3) Unless you keep an eye on the log file generated there is no other quick and simple way to debug your custom actions in Wix. I normally just display message boxes with debug information but when there are subtle issues in the Wix XML or your custom actions are complex and are failing silently the log file is the only way to go.
4) You CAN NOT have Deferred Custom Actions and normal Custom Actions as part of the same setup. The normal custom actions will throw security violation errors if they are part of the same Wix script.
5) In order for your custom actions to display debug message box's you need to ensure the WixUIExtension library is referenced by your Setup project.

Here is my .Net solution for a basic deferred custom action that simply displays the meta data handed down in message boxes.

Make note of the Wix XML that represents the deferred custom action.

Snippet
		<CustomAction Id="SetCustomActionDataValue" Return="check" Property="DisplayCustomActionData" Value="USERNAME=[USERNAME];PASSWORD=Say Hello to my little friend;" />
<CustomAction Id="DisplayCustomActionData" BinaryKey="WixerCustomActionsDLL" DllEntry="DisplayCustomActionData" Impersonate="no" Execute="deferred" Return="check" />

<InstallExecuteSequence>
<Custom Action="SetCustomActionDataValue" After="InstallFiles" ></Custom>
<Custom Action="DisplayCustomActionData" After="SetCustomActionDataValue" ></Custom>
</InstallExecuteSequence>

Useful notes:
Kicking of the Installer generated by the attached .Net solution with verbose logging : msiexec /i Wixer.Setup.msi /l*v test.log


Posted by jean with no comments

Useful resources on Wix & MSBuild

Rob Mensching's Blog
http://robmensching.com/blog/posts

Wix Edit on Sourceforge
http://wixedit.sourceforge.net/

General forum for Wix users
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/

Primary tutorial for Wix development
http://www.tramontana.co.hu/wix/lesson5.php#5.4

http://www.installworld.com/index.php?view=article&catid=41%3Awindows-installer-xml&id=113%3Awindows-installer-xml-standard-custom-actions&option=com_content&Itemid=137
http://stackoverflow.com/questions/313877/can-i-automate-creating-a-net-web-application-in-iis
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/IIS-actions-failing-td4971548.html

Wix & Burn
http://robmensching.com/blog/posts/2009/7/14/Lets-talk-about-Burn

Great Blog post on Wix
http://blogs.technet.com/b/alexshev/archive/2008/02/10/from-msi-to-wix.aspx

Set Asp.Net Version version Wix

http://stackoverflow.com/questions/163531/set-asp-net-version-using-wix

System folder properties
http://msdn.microsoft.com/en-us/library/aa372057.aspx

Wix article on code project
http://www.codeproject.com/KB/install/WixTutorial2.aspx

Wix toolset
http://wix.sourceforge.net/manual-wix3/files.htm

How do I install an ASP.NET application in IIS 7 using Wix
http://stackoverflow.com/questions/686190/how-do-i-install-an-asp-net-mvc-application-on-iis-7-using-wix

How to use Wix Custom actions with Appcmd.exe to set up virtual folders
http://trac.osgeo.org/mapguide/browser/trunk/Installer/Libraries/MapGuide%20Web%20Extensions/IIS7.wxs#L9

Wix 1419
http://wix.sourceforge.net/releases/3.5.1419.0/

Granting User rights in C#
http://stackoverflow.com/questions/1147914/why-might-lsaaddaccountrights-return-status-invalid-parameter
http://www.codeproject.com/KB/cs/lsadotnet.aspx

Custom Action Element
http://wix.sourceforge.net/manual-wix2/wix_xsd_customaction.htm
http://stackoverflow.com/questions/1213953/c-custom-action-in-wix

Great blog post on elevating priveledges with Custom Action's in Wix
http://blogs.msdn.com/b/astebner/archive/2006/12/13/some-useful-things-i-have-learned-about-windows-installer-and-uac.aspx

Debugging Custom Actions in Wix & Great Wix Resource
http://blog.torresdal.net/CategoryView,category,WiX.aspx

Wix 3.5 IIS Schema elements
http://wix.sourceforge.net/manual-wix3/iis_xsd_index.htm

All the Wix releases can be downloaded from here along with source code
http://wix.sourceforge.net/releases/

Information about ApplicationHost.config
http://learn.iis.net/page.aspx/124/introduction-to-applicationhostconfig/#HowTo

General article on custom actions

http://www.installworld.com/index.php?view=article&catid=41%3Awindows-installer-xml&id=113%3Awindows-installer-xml-standard-custom-actions&option=com_content&Itemid=137

Wix related BUGS and issues with MSBuild
http://blogs.msdn.com/b/msbuild/
http://stackoverflow.com/questions/2656389/why-does-tfs2010-build-my-wix-project-before-anything-else

Msdn article on Wix 2
http://msdn.microsoft.com/en-us/magazine/cc163456.aspx

Using wix with MSBuild

http://wix.sourceforge.net/manual-wix3/wix_with_team_build.htm

All candle variable references

http://blogs.msdn.com/b/jrock/archive/2008/01/29/complete-list-of-candle-preprocessor-variables.aspx

Posted by jean with no comments
Filed under:

Adventures with Wix 3.5, Visual Studio 2010 & Team foundation build 2008

Lately I have been having a look at the Microsoft Open Source project named Wix. The goal of this project is to provide an Xml DSL that allows the user to build deployment packages that are wrapped up in a Windows Installer package or ".Msi" file. The user can declare user interfaces that allow for additional meta data to be handed down to the installer and conditional information that will influence the deployment process. The meta data along with the components installed on the machine are registered with the Windows OS and on uninstall the removal instructions are executed which can once again query this meta data. Wix allows you to hook into or extend the component installation event sequence if required and custom actions (written in managed or unmanaged code) can query meta data provided by an Installer custom UI during install and uninstall.

Unfortunately Wix is not always 100% stable, and requires some knowledge of MSBuild and the Microsoft Build Engine.

Rob Mensching who works at Microsoft is the development lead on the project. Scott Hanselman interviews him on Hanselminutes podcast 195.

General rules when working with Wix 3.5 in a Visual Studio 2010 environment.

a) Always use the latest version of Wix 3.5. (At the moment the latest version is 3.5.1916)
b) Wix functionality is not completely extensive and very often requires the user to develop a "custom action" to achieve the required goal.
c) Never make any changes to the MS Build or Wix target files. Attempting such a feat will put you in a world of pain.
d) Make note of where the new Wix target files are located. All VS 2010 Wix project files need to reference the Wix2010.targets file.
e) Wix 3.0 and 3.5 cannot run side by side on the same server. Upgrading Wix 3.0 to Wix 3.5 is a one way street.
f)  Upgrading a solution from VS2008 to VS2010 will require you to upgrade Wix 3.0 to Wix 3.5 and will thus require you to manually edit each Wix project file and update the target file references in all of the wix project files (wixproj) referenced by the solution.

<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.5\Wix2010.targets</WixTargetsPath>
<WixToolPath>$(ProgramFiles)\Windows Installer XML v3.5\bin\</WixToolPath>

g) There is a bug with Visual Studio 2010 whereby Wix projects are automatically checked out if you edit a Wix XML file (.wxs). Hopefully this will be patched up with Visual Studio SP1.
h) There is no single location for Wix documentation unfortunately. My next blog post will include all the useful internet links that contained information about Wix and MSBuild.

Issues experienced with the Wix installation:

1)      Wix Merge module built after the installer thus causing the installer to fail. This was a bug with the Light.exe wix command line utility which linked Wix projects.

C:\Program Files\Windows Installer XML v3.5\bin\Light.exe ... error LGHT0129: Cannot open the merge module 'XXX' from file

'XXX.msm'.

The command exited with code 129.

Done executing task "Light" -- FAILED.

Done building target "Link" in project "YYY.wixproj" -- FAILED.

 

The bug has been “documented” here:

http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Problem-with-build-order-under-MSBuild-4-0-td4903964.html

 

2)      Ensure that you have an output path declared in your Wix project (.wixproj) file.

 <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

    <OutputPath>

                XXX

    </OutputPath>

otherwise the build will fail with:

 

heat.exe : error HEAT5313: Build error during harvesting: C:\Program Files\MSBuild\Microsoft\WiX\v3.5\Wix2010.targets(425,7): The OutputPath property is not set for this project.  Please check to make sure that you have specified a valid Configuration/Platform combination.  Configuration='Release'  Platform='AnyCPU'

[YYY.wixproj]

heat.exe : error HEAT5307: Build failed. [YYY.wixproj]

The command exited with code 5307.

Done executing task "HeatProject" -- FAILED.

Done building target "HarvestProjects" in project "YYY.wixproj" -- FAILED.

Target "_CheckForCompileAndLinkOutputs" in file "C:\Program Files\MSBuild\Microsoft\WiX\v3.5\Wix2010.targets" from project

3)      This is quite obvious but ensure that all your Wix extension projects (i.e. those which use the wix.dll) have been deployed to the Wix target bin folder(C:\Program Files\Windows Installer XML v3.5\bin) otherwise you will receive the following error:

candle.exe : error CNDL0144: The extension 'C:\Program Files\Windows Installer XML v3.5\bin\XXXWixExtension.dll' could not be loaded because of the following reason: Could not load file or assembly 'file:///C:\Program Files\Windows Installer XML v3.5\bin\XXXWixExtension.dll' or one of its dependencies. The system cannot find the file specified. [YYY.wixproj]

The command exited with code 144.

Done executing task "Candle" -- FAILED.

Done building target "Compile" in project "YYY.wixproj" -- FAILED.

Target "_CheckForCompileAndLinkOutputs" in file "C:\Program Files\MSBuild\Microsoft\WiX\v3.5\Wix2010.targets" from project "YYY.wixproj" (target "_CleanGetCurrentAndPriorFileWrites" depends on it):

Task "CreateItem" skipped, due to false condition; (Exists('%(FullPath)')) was evaluated as (Exists('')).

Task "CreateItem" skipped, due to false condition; (Exists('%(FullPath)')) was evaluated as (Exists('XXX.msi')).

 

Visual Studio IDE bugs relating to which have now been resolved with the latest version of Wix:

a)      Custom actions project type was missing in Wix3.5 1419. This led me to believe that a normal C# library which references the Microsoft.Deployment.WindowsInstaller library would suffice as a custom action library which unfortunately is NOT the case. Upgrading to Wix Version 3.5.1916 fixes this problem.


b)      Make sure you specify Mixed platforms as the active solution platform for the solution which Team Foundation Build will be using. Configuration manager can be found in Visual Studio under Build --> Configuration Manager.

 

Hope this helps all the Wixers out there...

 

Interesting Finds - 04/07/2010

New features in MVC2
http://www.asp.net/learn/whitepapers/what-is-new-in-aspnet-mvc

ASP.Net MVC architecture Video by Rob Connery
http://www.asp.net/mvc/videos/what-is-aspnet-mvc-80-minute-technical-video-for-developers-building-nerddinner

DevExpress Asp.Net MVC extensions
http://mvc.devexpress.com/GridView/Scrolling

DevExpress online demos
http://www.devexpress.com/Downloads/NET/OnlineDemos.xml

DevExpress MVC controls integration Video
http://tv.devexpress.com/#MVCsupport.movie

Great blog post by Mr Hanselman on ASP.NET Webforms / MVC hybrids
http://www.hanselman.com/blog/PlugInHybridsASPNETWebFormsAndASPMVCAndASPNETDynamicDataSideBySide.aspx

Great blog post with source code on how to use Velocity with an ASP.NET applicatoin
http://cgeers.wordpress.com/2010/07/04/windows-server-appfabric-caching/

Great articles to read:

Scott Mitchell - LinqToXml
http://www.4guysfromrolla.com/articles/062310-1.aspx

Scott Guthrie - The new View Engine for ASP.NET
http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx

Cool article on the MVC contrib grid which has column sorting!
http://www.codecapers.com/post/Looking-for-an-MVC-Grid-Control-Try-MVC-Contrib!.aspx

Latest Version of StyleCop 4.4.0
http://stylecop.codeplex.com/releases/view/44839

The electric cool-aid acid test by Rob Connerty. A good talk about keeping an open mind. :-)
http://66.29.219.11/conery_ndc_talk.mp4

Posted by jean with no comments
Filed under:

WCF NetTcpBinding ProtectionLevel security performance test

Normally within 3 Tier applications that leverage the NetTcpBinding behind a firewall within an intranet environment I prefer to switch off security altogether since this is a trusted network zone and performace should be maximised in this case. There are times when this environment may not be trusted in which case you will need to start tweeking the relevant WCF security settings. Understanding the performance ramifications when enabling security is very important in my opinion. I was recently interested in the ProtectionLevel security setting which can be set imperatively or declaratively... so I knocked up the following performace test to see what the different performace ramifications are for the three possible options relating to ProtectionLevel.

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.ServiceModel;

using System.Net.Security;

using System.Diagnostics;

 

namespace ConsoleApplication1

{

    //This is the minimum protection level that the binding must comply with.

    [ServiceContract(ProtectionLevel = ProtectionLevel.None)]

    public interface IConvertString

    {

        [OperationContract]

        string ConvertString(string input);

    }

 

    // Simple service which reverses a string and returns the result

    public class ConvertStringService : IConvertString

    {

        #region IConvertString Members

 

        public string ConvertString(string input)

        {

            char[] chars = input.ToCharArray();

            chars.Reverse<char>();

            return chars.ToString();

        }

 

        #endregion

    }

 

    class Program

    {

        // Setup the Service host

        private static ServiceHost StartServer<T>(string Uri, NetTcpBinding binding)

        {

            Uri uri = new Uri(Uri);

 

            ServiceHost host = new ServiceHost(typeof(ConvertStringService));

            host.AddServiceEndpoint(typeof(T), binding, uri);

            host.Open();

 

            Console.WriteLine("Service opened using NetTcpBinding with {0} protection level.", Enum.GetName(typeof(ProtectionLevel), binding.Security.Transport.ProtectionLevel));

 

            return host;

        }

 

        // Create channel using NetTcp binding with Uri and execute performance test.

        private static double RunPerformanceTestOnNetTcpBinding(NetTcpBinding binding, string endpointUri)

        {

            const int iterations = 300;

            const string stringToConvert = "12";

 

            Stopwatch watch = new Stopwatch();

            watch.Start();

            for (Int32 i = 0; i < iterations; i++)

            {

                ChannelFactory<IConvertString>.CreateChannel(binding,

                    new EndpointAddress(endpointUri))

                    .ConvertString(stringToConvert);

            }

            watch.Stop();

 

            Console.WriteLine("ConvertString with ProtectionLevel {2} : {0} times; Time taken : {1} ",

                iterations.ToString(),

                watch.Elapsed.TotalSeconds.ToString(),

                Enum.GetName(typeof(ProtectionLevel), binding.Security.Transport.ProtectionLevel));

 

            return watch.Elapsed.TotalSeconds;

 

        }

 

        static void Main(string[] args)

        {

 

            string uri = "net.tcp://localhost:7000/IConvertString";

 

            NetTcpBinding bindingNoEncryption = new NetTcpBinding();

            bindingNoEncryption.Security.Mode = SecurityMode.Transport;

            bindingNoEncryption.Security.Transport.ProtectionLevel = ProtectionLevel.None;

 

            NetTcpBinding bindingWithSign = new NetTcpBinding();

            bindingWithSign.Security.Mode = SecurityMode.Transport;

            bindingWithSign.Security.Transport.ProtectionLevel = ProtectionLevel.Sign;

 

            NetTcpBinding bindingWithEncryption = new NetTcpBinding();

            bindingWithEncryption.Security.Mode = SecurityMode.Transport;

            bindingWithEncryption.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;

 

            Console.WriteLine("Run performance test or press q to Quit...");

            while (Console.ReadLine() != "q")

            {

 

                double noEncryptionTime;

                double signTime;

                double encryptionTime;

 

                using (ServiceHost host = StartServer<IConvertString>(uri, bindingNoEncryption))

                {

 

                    noEncryptionTime = RunPerformanceTestOnNetTcpBinding(bindingNoEncryption, uri);

                    host.Close();

                }

 

                using (ServiceHost host = StartServer<IConvertString>(uri, bindingWithSign))

                {

                    signTime = RunPerformanceTestOnNetTcpBinding(bindingWithSign, uri);

                    host.Close();

                }

 

                using (ServiceHost host = StartServer<IConvertString>(uri, bindingWithEncryption))

                {

                    encryptionTime = RunPerformanceTestOnNetTcpBinding(bindingWithEncryption, uri);

                    host.Close();

                }

 

                Console.WriteLine("Run performance test again or press 'q' to Quit...");

 

           }

 

        }

 

    }

 

}

 

The results from my performance test were interesting.... see below:

 

As you can see from the above tests the when using Transport security with the NetTcpBinding ProtectionLevel Sign performance is not much different to EncryptAndSign, although there is a definite performance increase when using Protection Level None.

Additional resources:

Understanding Protection Level

 

Posted by jean with no comments
Filed under:

Using Rx for Event subscription

I thought I would have a quick look to determine wether Rx would create a strong reference under the hood or not when one object subscribed to another objects events. In this case the Consumer object subscribes to the SampleData objects's SampleDataChanged event. This type of strong reference causes memory leaks in applications because the garbage collector will not clean up the event consumer even though the consumer may be out of scope. The result of my testing indicates that unfortunately there is still a strong reference because once the Consumer object goes out of scope and once Garbage collection has been called, calling the event on SampleData still causes the event to be raised in the Consumer meaning that the consumer has not been garbage collected. Can I use the System.WeakReference object to resolve this issue? I will follow up on this shortly...


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace WeakReferenceTestConsole

{

    class Program

    {

 

        static void Main(string[] args)

        {

 

            SampleData sampleData = new SampleData();

 

            for (int i = 0; i < 3; i++)

            {

                WorkOnData(sampleData, i);

            }

 

            sampleData.RaiseSampleDataChanged("Sample Data change - Consumer outside scope");

 

            // Force garbage collection

            GC.Collect();

            GC.WaitForPendingFinalizers();

 

            sampleData.RaiseSampleDataChanged("Sample Data change - Consumer outside scope - After garbage collection");

 

            Console.ReadKey();

        }

 

        private static void WorkOnData(SampleData sampleData, int iteration)

        {

            // Create a consumer which registers a method with the sample data objects SampleDataChanged event

            Consumer consumer = new Consumer(sampleData);

            consumer.Name = "Consumer " + iteration.ToString();

 

            //Raise the sample data object's data changed event

            sampleData.RaiseSampleDataChanged("Work on data - iteration : " + iteration.ToString());

        }

 

    }

 

    public class Consumer

    {

 

        //private SampleData _sampleData;

 

        public Consumer(SampleData sampleData)

        {

            //_sampleData = sampleData;

            //sampleData.SampleDataChanged += new SampleData.SampleDataChangedEventHandler(Consumer_SampleDataChanged);

 

            Observable.FromEvent<SampleDataChangedEventArgs>(sampleData, "SampleDataChanged").Subscribe(

                args =>

                Consumer_SampleDataChanged(sampleData, (SampleDataChangedEventArgs)args.EventArgs)

                );

 

        }

 

        public string Name { get; set; }

 

        void Consumer_SampleDataChanged(object sender, SampleDataChangedEventArgs e)

        {

            Console.WriteLine("Sample Data Changed : {0} - Notified Consumer : {1}", e.Message, this.Name);

        }

 

        ~Consumer()

        {

            Console.WriteLine("Consumer finalizer");

        }

    }

 

    public class SampleData

    {

        public event SampleDataChangedEventHandler SampleDataChanged;

        public delegate void SampleDataChangedEventHandler(object sender, SampleDataChangedEventArgs e);

 

        public void RaiseSampleDataChanged(string message)

        {

            SampleDataChangedEventHandler handler = SampleDataChanged;

 

            if (handler != null)

            {

 

                SampleDataChangedEventArgs e = new SampleDataChangedEventArgs(message);

                SampleDataChanged(this, e);

            }

 

        }

 

    }

 

    public class SampleDataChangedEventArgs : EventArgs

    {

        public SampleDataChangedEventArgs(string message)

        {

            this.Message = message;

        }

 

        public string Message { get; set; }

    }

 

 

}

 

 

 

The enemy within. A bleak view into the lack of regulation in the IT industry.

“I value simplicity over everything; I always look for simplicity.”

 Anders Hejlsberg quote

As a programmer I love writing code. Make no mistake. I love flexing my mind and seeing if I can find a short and elegant route to the solution required to resolve a problem or satisfy a business requirement. The key words in that sentence are "short" and "elegant". What I mean by those words are that I prefer the fewest lines of code possible and I feel a strong need to leverage the available technologies in the most efficient and effective manner possible. Since I am a C# programmer, "efficient" means selecting the necessary 3rd party libraries or preferably using the standard libraries that come with the .Net framework that provide acceptable performance. "Effective" meaning they solve the problem in a way that produces the minimum amount of technical debt.

My favourite saying has always been "The only thing I enjoy more than writing code ... is deleting code." What I mean by this is that when I approach a legacy application in order to make changes to it or to update the functionality I keep a keen eye on attempting to identify the areas where I can delete unnecessary code.

This includes:

a) Code that has been is duplicated, not properly encapsulated into re-usable units.

b) Identifying areas where the wheel has been re-invented. An API or set of tools/libraries already existed that do the job in a more elegant (and probably more efficient) manner.

c) Identifying areas where there are unnecessary abstractions or layers of indirection.

I firmly believe that it is our duty as programmers to build maintainable and scalable applications which minimize the level of complexity within the code we write. By managing the complexity within the code we write we are able to handle and thus implement more complex business rules. This leads me onto the main reason for this blog post... The problem is that programmers admire complexity and sometimes over complicate solutions to gain "intellectual control" over the code they produce. The more difficult or complex a solution the more likely the business will develop a dependency on the developer that built that solution to maintain that solution, since they understand the solution the best and would require the least amount of time to make bug fixes or updates to the code. Management are unable to identify code that has been made to be unnecessarily complex, and when they do they are presented with reasons such as "The solution is re-usable" or "We might need that functionality for scenario A...", and needless to say scenario A is as inevitable as being hit by a meteorite.... Possible but highly unlikely.

At the moment the IT industry is suffering from the following symptoms:

1) Legacy systems that have been difficult to maintain and are undocumented.

2) Having developers take control of the core of the business by becoming dependent on the custom in house Software built to run the business.

3) Having no control mechanisms in place that will review code written by the developers.

As Billy Hollis rightly states we are all code addicts as programmers, and we need to fight this code addiction. We the programmers must avoid becoming the enemy within the organization and ensure our code is maintainable and well documented. I will attempt to provide a set of processes which management can put in place to avoid the symptoms mentioned above.

Posted by jean with no comments
Filed under:

Interesting finds - 24 May 2010

Great Ildasm.exe tutorial from MSDN
http://msdn.microsoft.com/en-us/library/aa309387(v=VS.71).aspx

Rx Extensions - Good blog post by Haacked.
http://haacked.com/archive/2010/03/26/enumerating-future.aspx

Eugene Prystupa's Blog: - Short simple and powerful ideas regarding Rx, Serialization, and MVVM
http://eprystupa.wordpress.com/

Matt Hidinger's Blog - Great MVC / Unit Testing / Entity Framework T4 Template posts

http://feeds.feedburner.com/mhidinger

AutoIT Great UI automation testing tool

http://www.autoitscript.com/autoit3/downloads.shtml

Nicolas Allen's blog - Great resource for those interested in WCF
http://blogs.msdn.com/drnick/pages/technologies-of-interest-to-wcf-developers.aspx

Linq To Xml Overview
http://msdn.microsoft.com/en-us/library/bb308960.aspx#xlinqoverview_topic2g
http://msdn.microsoft.com/en-us/library/bb387098(v=VS.100).aspx

Introduction to WPF
http://msdn.microsoft.com/en-us/library/aa970268(v=VS.100).aspx

Introduction to databinding in WPF
http://msdn.microsoft.com/en-us/library/ms752347.aspx

Posted by jean with no comments
Filed under:

Loading and executing .Net code from an external file dynamically

I've recently been tasked with writing a service which will allow me to dynamically load code from a file and inject it into an assembly at run-time for execution. The injected code will need to implement the IXmlQueryService interface. The input stream will contain the original Xml and the output stream will contain the enriched Xml. Linq to Xml is used to update the Xml from the input stream and write out the results to the output stream.

[XmlEnrichmentService.cs]

using System;

using System.IO;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Xml.Linq;

using System.Xml;

 

namespace XmlEnrichmentTestConsole

{

    // This is the code which is injected into the application at run-time

    public class XmlEnrichmentService : IXmlEnrichmentService

    {

        #region IXmlEnrichmentService Members

 

        public void EnrichXml(TextReader inputXmlStream, TextWriter outputXmlStream)

        {

            // Load the XML into the Xdocument object

            XDocument purchaseOrder = XDocument.Parse(inputXmlStream.ReadToEnd());

 

            // Extract the nodes you are interested in using Linq To Xml

            List<XElement> partNos =

                    (from item in purchaseOrder.Descendants("Item")

                     where (int)item.Element("Quantity") *

                         (decimal)item.Element("USPrice") > 100

                     orderby (string)item.Element("PartNumber")

                     select item).ToList();

 

            // Add the enrichment data

            partNos.ForEach(xElem =>

            {

                xElem.Add(new XElement("newElement",

                                new XElement("newElementChild1", "ENRICHMENT DATA")));

            });

 

            // Write the enriched XML to the output stream

            outputXmlStream.Write(purchaseOrder.ToString());

 

            outputXmlStream.Flush();

        }

 

        #endregion

    }

}


The CodeDomProvider will be used to compile and generate the assembly containing the XmlEnrichmentService.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

using System.IO;

using System.Reflection;

using System.CodeDom.Compiler;

 

using Microsoft.CSharp;

using Microsoft.VisualBasic;

using System.Collections;

 

namespace XmlEnrichmentTestConsole

{

 

    public interface IXmlEnrichmentService

    {

        void EnrichXml(TextReader inputXmlStream, TextWriter outputXmlStream);

    }

 

    public class TestLoader

    {

 

        public static void TestXmlEnrichment()

        {

            using (StreamReader inputXmlStream = new StreamReader(@"CodeCompiler/PurchaseOrder.xml", Encoding.Default))

            {

                using (StreamWriter outputXmlStream = new StreamWriter(@"d:\temp\EnrichedPurchaseOrder.xml", false))

                {

 

                    StreamReader enrichmentCodeStream = new StreamReader(@"CodeCompiler/XmlEnrichmentService.cs");

 

                    CodeDomProvider codeCompiler = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v3.5" } });

 

                    CompilerParameters compilerParameters = new CompilerParameters();

                    compilerParameters.GenerateExecutable = false;

                    compilerParameters.GenerateInMemory = false;

                    compilerParameters.WarningLevel = 3;

                    compilerParameters.TreatWarningsAsErrors = false;

                    compilerParameters.CompilerOptions = "/optimize";

 

                    var assemblyNames = (from assembly in AppDomain.CurrentDomain.GetAssemblies()

                                         select new { Name = assembly.GetName().Name, Location = assembly.Location }).ToList();

 

                    // Extract the current domain's referenced assemblies

                    assemblyNames.ForEach(assembly => compilerParameters.ReferencedAssemblies.Add(assembly.Location));

 

                    // Compile the external source code file

                    CompilerResults compilerResults = codeCompiler.CompileAssemblyFromSource(compilerParameters, enrichmentCodeStream.ReadToEnd());

 

                    // Display compiler error results if there are any

                    if (compilerResults.Errors.HasErrors)

                    {

                        foreach (string line in compilerResults.Output)

                        {

                            Console.WriteLine(line);

                        }

                        return;

                    }

 

                    Assembly assemblyToLoad = Assembly.LoadFrom(compilerResults.PathToAssembly);

 

                    Type enrichmentServiceType = (from lt in assemblyToLoad.GetTypes()

                                                  where lt.GetInterface(typeof(IXmlEnrichmentService).Name) != null

                                                  select lt).SingleOrDefault();

 

                    if (enrichmentServiceType == null)

                        throw new NullReferenceException("Xml Enrichment Service could not be found.");

 

                    IXmlEnrichmentService enrichmentService = (IXmlEnrichmentService)Activator.CreateInstance(enrichmentServiceType);

 

                    try

                    {

                        enrichmentService.EnrichXml(inputXmlStream, outputXmlStream);

                    }

                    catch (Exception exception)

                    {

                        throw exception;

                    }

 

                }

            }

        }

 

 

    }

}


The generated  assembly is then loaded using Assembly.LoadFrom from the compilerResults.PathToAssembly and then Linq is used to discover the class which implements the IXmlEnrichmentService.

Posted by jean with no comments

Reactive Extensions for .NET (Rx) : Resources

I have recently started playing with the new Rx Extension Libraries for .net. These extensions provide the programmer with a new model for event subscription where by we can write a linq statement to query a future set of events. The power from this model is that code for event subscription is more clear AND events are handled in an asynchronous manner within the subscriber. A set of Rx extension libraries have also been made available to Java Script programmers.

The IEnumerable's counterpart is the IObserverable and the IEnumerator's counterpart is the IObserver. See below...

public interface IObservable<T>

{

  IDisposable Subscribe(IObserver<T> observer);

}

public interface IObserver<T>

{

  void OnNext(T value);

  void OnCompleted();

  void OnError(Exception exception);

}

Resources:

DevLabs: The main site where you can download the Rx Assemblies
http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

DevLabs Forums : General up to date information from the Rx community
http://social.msdn.microsoft.com/Forums/en-US/rx/threads

Rx Wiki : A good source of example code and information.
http://rxwiki.wikidot.com/

Channel9
http://channel9.msdn.com/tags/Reactive+Framework/
http://channel9.msdn.com/tags/Rx/
http://channel9.msdn.com/tags/Reactive+Extensions/

Blogs
http://mnajder.blogspot.com/search/label/Rx
http://weblogs.asp.net/sweinstein/archive/tags/RX/default.aspx
http://themechanicalbride.blogspot.com/2009/07/introducing-rx-linq-to-events.html
http://codebetter.com/blogs/matthew.podwysocki/archive/2009/10/14/introducing-the-reactive-framework-part-i.aspx

Posted by jean with no comments

Interesting Finds - 9 May 2010

OData - The official team blog
http://blogs.msdn.com/astoriateam/archive/2010/03/16/announcing-the-odata-sdk.aspx

Great channel 9 video on WPF development / Southridge starterkit download information
(Datagrid / WPF Ribbon)
http://channel9.msdn.com/pdc2008/PC45/

Marcin Nadjer Reactive extensions Blog (This guy knows his stuff ;-))
http://mnajder.blogspot.com/search/label/Rx

Great blog post on WPF 4 and New WPF controls by the one and only Scott Gu
http://weblogs.asp.net/scottgu/archive/2009/10/26/wpf-4-vs-2010-and-net-4-0-series.aspx

Southridge lab codeplex download location. + Links to wpf ribbon download location.
http://wpf.codeplex.com/releases/view/14962
http://www.codeplex.com/wikipage?ProjectName=wpf&title=WPF%20Ribbon%20Preview

Official Ribbon control walkthrough
http://windowsclient.net/wpf/wpf35/wpf-35sp1-ribbon-walkthrough.aspx

Unity 2.0 framework download location
http://unity.codeplex.com/

Gregory Melnik's blog - Enterprise library 5.0 / Unity 2.0 information
http://blogs.msdn.com/agile/default.aspx

Enterprise Library 5.0 download location on codeplex
http://entlib.codeplex.com/

General:
Global Visas complaints board
http://www.complaintsboard.com/complaints/global-visas-c163585.html

Posted by jean with no comments
Filed under:

Global Visas UK - Fraud

I have recently had a bad experience with a company called Global Visas here in the UK. My fiance and I approached Global Visas hoping to learn what it would entail to obtain a particular Visa.

The following set of events occurred:

1) I phoned global visas and requested information what was required to kick off the Visa application process.
I got put through to an "agent" who said I needed to open a case at the cost of 100£ and my case would be put forward to a "case worker".
I handed over my debit card details and they deducted 100£.

2) The agent then sent through a set of documents one of them being the "Client Care Letter". Without having read the documentation I proceeded to make an appointment with a case worker to determine what the Visa application process would entail, and to discuss fees.

3) During the consultation the case worker gave me no indication that by the mere fact that I was attending the consultation and had paid the £100 that the process had already been kicked off and that I was liable for the full amount of approximately £1800.

I had at no point read the client care letter even or even verbally given my approval to kick off the Visa application process. I had signed nothing either. I was completely unaware that according to them I had kicked off the Visa application process, and Global Visas made no effort to inform me at any point. I went on holiday with my fiance and after returning I noticed that an amount of approximately £700 had been deducted from my debit card without my consent. After attempting to reach my Case worker I managed to get through to the Agent (Bosco) who I initially spoke to and asked him why the money had been deducted from my account. His reaction was aggressive and completely unsympathetic and continued to accuse me of using Global Visa's services without intent to pay.

Global Visas has deducted the £700 installment from my account using the Visa debit card details they had initially obtained from my £100 fee payment. They had illegally held on to my debit card details without my knowledge or consent.

They gave me no indication that the first installment of £700 would be deducted after our initial consultation and my fiance and I
explicitly indicated that we were not sure whether we would even be applying for the Visa's at all.

By deducting the initial service fee from my account without proper consent I felt that Global Visas had unlawfully executed the
transaction for the initial fee in an attempt to tie us in to the contract. I then continued to raise a "Visa Dispute" with my bank and have been refunded the amount which was deducted by Global Visas. Through further investigation on the internet I realized that Global Visas has a name for doing such things.

A similar complaint about Global Visas UK:
http://www.complaintsboard.com/complaints/global-visas-c259741.html

The office of immigration which regulates Global Visas:

http://www.oisc.gov.uk/complaints_about_immigration_advice/


I discovered the following information in the "Client Care letter":

"After we have given you all the information and advice we can during our consultation process, you must pay our fees in full.  In line with best practice and the DSR, you are entitled to cancel this agreement up to the point where we start to provide our expert information and you accept these conditions when you pay our fees. 

Once we have provided you with our knowledge during our consultation process our full fees are payable.  As part of our service and commitment to you we are happy to assist with the following services:

You may end this contract at any time by writing to us to tell us that you are ending your agreement. But you will be legally responsible for paying any money you owe us for our fees or extra fees. You will have to pay this money even if we have asked for any of these fees at the time you end this agreement."

This is how Global Visas bully you into a contract with them.

Posted by jean with no comments
Filed under: ,

Find a user's Active Directory groups.

I like simple solutions. Fortunately the .Net Framework API's are slowly evolving to make life simpler for the architect and programmer. One new .Net 3.5 framework library which I am very happy with is System.DirectoryServices.AccountManagement. Have a look at how simple it is to find the groups an AD user belongs to.

Add a reference to System.DirectoryServices and System.DirectoryServices.AccountManagement.

 

using System;
using System.Collections.Generic;
using System.Linq;

using System.DirectoryServices.AccountManagement;

namespace DetermineUserGroupsConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            //Initializes a new instance of the System.DirectoryServices.AccountManagement.PrincipalContext
            //class with the specified context type.
            PrincipalContext principalContext = new PrincipalContext(ContextType.Machine);
            UserPrincipal userPrinciple = UserPrincipal.FindByIdentity(principalContext, IdentityType.Name, "EHS\\jean");

            // Select a list of group names from the PrincipalSearchResult<Principal>
            var userGroups = from userGroup in userPrinciple.GetGroups()
                             select userGroup.Name;
            
            foreach (string groupName in userGroups)
            {
                System.Console.WriteLine(groupName);
            }

            System.Console.ReadKey();
        }
    }
}

 

Have a look at the MSDN site or codeproject for further information on this topic.

Hope this was helpfull. 

Posted by jean with no comments
Filed under:
More Posts Next page »