Sunday, 6 January 2013

Optimising for Happiness

I've been fortunate to work on some very successful Agile teams that were focused on either building a software product or maintaining a legacy software system.

I thought it I'd share some of my insights relating to Agile Software Development Practices:
  1. Motivation: Members of an Agile team need to communicate constantly. Through scrums, design sessions and pair programming. Team members that are not motivated will not communicate effectively with other members. Ensuring that the team members are positive and are able to approach one another easily is critical.
  2. Prototypes: As user stories get picked up by the developers they need to demonstrate their initial implementations to the business analyst who worked on the story. These demonstrations help guide the developers in the right direction and give the business analyst(or user) an idea of how the system is evolving over time. Misunderstandings get picked up quickly and resolved early. This also prevents unnecessary changes to the system further down the line.
  3. Focus on the critical path: A full front-end to back-end system prototype needs to be delivered as early as possible. This forces the team to focus on the user stories that form the core of the system, and helps avoid unnecessary scope creep. I don't think there has ever been a system that I was not able to break down into between 6 and 8 core stories that would break the back of the system, and provide a full end-to-end demonstration. 
  4. Test driven development (TDD): This is a practice that many believe increases code quality and provides the team with unit tests around their core services. While this is true, test driven development is really a practice that I have rarely seen developers get right. The ones that got is right used TDD as a design tool for their Service API's, and ensured that the complex system services had the appropriate unit tests. Test driven development can also be abused by some developers who have a "code addiction" = Love writing unnecessary code. 
  5. Administration: Administration tasks need to be minimised. Micromanagement of one's time is a real killer here. The Kanban board is great for reducing administration related to tracking progress and can be used to maximise progress transparency.
  6. Documentation: This is the dark horse. The truth is there are certain user stories that require documentation and some that don't. Quality over quantity is the mantra. I have seen a team use wikis very effectively to document processes, set-up and administration tasks. This effectively reduces the email trail. If the business analysts are experienced with the technology screenshots are always a very nice to have. Screenshots say a thousand words and clear up the implementation specific early. The following types of information should accompany screenshots:
    1. - Overall summary of what the business requirement and how the screen satisfies this requirement.
    2. - A small section for each control on the screen that includes the following information: What data is displayed, the format of the data, the validation rules that apply to the control.
  7. Extreme programming (XP): can be leveraged for the following reasons:
    1. - To train up junior developers on the system framework.
    2. - To allow senior developers the opportunity to assist one another to complete a user story.
    3. - To avoid silos of information in the development team.
  8. Spikes: This occurs when a developer picks up a story that requires some sort of investigation into the technical implementation options for completing the user story. The developer will set allocate a fixed time period with the Team lead and will spend that time investigating the various options outside the framework of the project. No developer is expected to know everything about a technology and can use these spike periods to perform the research they need to identify a feasible solution.
  9. Retrospective meetings: allow the team to reflect on past sprint iterations(short time periods - normally 2-3 weeks between client demonstrations) on the successes and failures of the sprint. The team is allowed to evolve and adapt the administrative and management process, thus leading to a scenario where they become 'self managed'. Another great thing about retrospective meetings is that by allowing team members to raise their gripes is that there is some form of accountability across the team.

Extract full list of twitter favourites using LinqToTwitter

Extracting a full list of twitter favourites means querying the Twitter REST API.

I've been looking for a website or app that would allow me to do this easily but have not found anything yet. The only way to extract a full list of twitter favourites would be to go onto twitter (or access your twitter app) and page manually through all your favourites. As a quick and dirty solution I thought I would use LinqToTwitter against the Twitter REST API. LinqToTwitter is a third party Linq Provider for generating URLs against the Twitter REST API and additionally providing the client with Authentication features to allow for API access.

1. Create a Twitter account : www.twitter.com

2. Sign in with account at : dev.twitter.com.
- Select your login name and navigate to the menu option : My Applications
- Click 'Create a new application' button

This will take you through the steps to expose the Twitter API for your application.
-Make note of the Consumer Key and Consumer Secret provided for the code snippet below.

3. Download and run the console application. The console application will automatically open a browser window displaying a pin number from twitter, that you need to type into the console window. Once that's done the console application will continue to query twitter (page by page) and will generate a html page with your full list of twitter favourites.

My full list of twitter favourites.

Tuesday, 3 July 2012

Reactive Extensions (Unplugged) : Using Rx to write non-blocking code

Writing non-blocking code helps us ensure we have responsive UI's, save resources by not having blocked threads, and take advantage of multiple cores.

Rx provides us with a few extension methods on the Observable class that allow us to expose an IObservable instead of having to use the classic Asynchronous Programming model which can be a little combersome.

Here are a few very basic examples:

namespace RxDemoApp
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reactive.Concurrency;
    using System.Reactive.Linq;
 
    /// <summary>
    /// The various ways of making the GetPrimes function non-blocking or asynchronous
    /// </summary>
    class NonBlockingDemo
    {
        internal static void Run(IScheduler subscriptionScheduler, IScheduler observationScheduler, long maxPrimeNumber)
        {
            Func<longIEnumerable<long>> func = Util.GetPrimes;
 
            // Using classic APM
            AsyncCallback callback = ar =>
            {
                IEnumerable<long> result = func.EndInvoke(ar);
                Util.WriteToConsole<string>(String.Format("Sum of numbers is: {0}", result.Sum()));
            };
            func.BeginInvoke(maxPrimeNumber, callback, null);
 
            Util.EndExample("Completed APM invocation.");
 
            // Using FromAsyncPattern
            Func<longIObservable<IEnumerable<long>>> ofunc1 = Observable.FromAsyncPattern<longIEnumerable<long>>
                (func.BeginInvoke, func.EndInvoke);
            ofunc1(maxPrimeNumber).SubscribeOn(subscriptionScheduler).ObserveOn(observationScheduler)
                .Subscribe(result =>
            {
                Util.WriteToConsole<string>(String.Format("Sum of numbers is: {0}", result.Sum()));
            });
 
            Util.EndExample("Completed FromAsyncPattern invocation.");
 
            // Using ToAsync
            Func<longIObservable<IEnumerable<long>>> ofunc2 = func.ToAsync();
            ofunc2(maxPrimeNumber).SubscribeOn(subscriptionScheduler).ObserveOn(observationScheduler)
                .Subscribe(result =>
            {
                Util.WriteToConsole<string>(String.Format("Sum of numbers is: {0}", result.Sum()));
            });
 
            Util.EndExample("Completed ToAsync invocation.");
 
            //Observable.Start
            Observable.Start(() => Util.GetPrimes(maxPrimeNumber)).SubscribeOn(subscriptionScheduler)
                .ObserveOn(observationScheduler)
                .Subscribe(result =>
            {
                Util.WriteToConsole<string>(String.Format("Sum of numbers is: {0}", result.Sum()));
            });
 
            Util.EndExample("Completed Observable.Start invocation.");
        }
    }
}

Monday, 2 July 2012

Reactive Extensions (Unplugged) - Rx vs Events

In this blog post I am just going to compare what is looks like to raise an event the classic way versus using Reactive Extensions (Rx).

I don't get much time to blog, but when I do get the occasional free hour or two I want to do my best just to keep the post simple and maybe show of some re-usable snippets of code that other developers can use. If you do need a deeper understanding of Rx, it's definitely worth reading the various blog posts, and books you can find out there on the subject. I have been fortunate enough to have had the opportunity to use the Reactive Extensions Framework on various Silverlight projects and it caught my interest. I am not going to go through the absolute basics on Rx in my blog posts because that has been done a thousand times already, but will rather show you a few simple insights that you may be able to use. All you need is the Rx-Main package from nuget.

It showed me a simpler (and cleaner) way to work with events and event streams:
This includes the consumption, filtering, composition of event streams, and the scheduling of work on the required thread (which is always useful in our Single Threaded Apartment model).

In the code below you can see that I am using Rx at the bottom to raise an event by calling OnNext which will in turn call the printToConsole function. Additionally I have used filtering and specified that I would like to inform the consumer that the event is the only event in the stream by calling OnCompleted. Since the "handle" returned from the Subscribe method implements IDisposable I can use the "Using" keyword to ensure the unsubscribe occurs at the end of the block.

namespace RxDemoApp
{
    using System;
 
    using System.Reactive.Subjects;
    using System.Threading;
 
    using System.Reactive.Linq;
 
    /// <summary>
    /// Demonstrates the different ways of exposing and subscribing to events
    /// </summary>
   class RxVsEventsDemo
    {
 
        delegate string onChangedHandler(long num);
        event onChangedHandler onChanged;
 
        delegate string MyEventHandler<T>(T value);
        event MyEventHandler<long> onChanged1;
 
        event Func<longstring> onChanged2;
 
        Subject<long> onChanged3 = new Subject<long>();
 
        internal static void Run()
        {
            RxVsEventsDemo demo = new RxVsEventsDemo();
 
            Func<longstring> printToConsole = num => 
            { 
                string message = String.Format("Message on thread {1} : Output value : {0}", 
                    num, 
                    Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine(message);
                return message;
            };
 
            // Using classic event handler
            onChangedHandler handler = new onChangedHandler(printToConsole);
            demo.onChanged += handler;
            demo.onChanged(10);
            demo.onChanged -= handler;
 
            // Wiring an event handler to an anonymous delegate
            Func<longstring> func = arg => printToConsole(11);
            
            //onChangedHandler handler1 = func; //Does not work
            onChangedHandler handler1 = arg => printToConsole(11);
            demo.onChanged += handler1;
            demo.onChanged(11);
            demo.onChanged -= handler1;
 
            MyEventHandler<long> handler2 = new MyEventHandler<long>(printToConsole);
            demo.onChanged1 += handler2;
            demo.onChanged1(11);
            demo.onChanged1 -= handler2;
 
            // Using a func
            demo.onChanged2 += printToConsole;
            demo.onChanged2(30);
            demo.onChanged2 -= printToConsole;
 
            //using Rx
            using (demo.onChanged3
                .Where(arg => arg % 2 ==0) // Reactive.Linq extension methods also allow the filtering of events
                .Subscribe((arg) => printToConsole(arg), 
                () => Util.WriteToConsole<string>("Done!!"))) // An additional OnCompleted(and OnError) action used
            {
                demo.onChanged3.OnNext(41); // Never raised because 41 is not an even number i.e. it was filtered out
                demo.onChanged3.OnCompleted();
            }
        }
    }
}

Sunday, 8 April 2012

Dynamically compiling code in memory using the CodeDomProvider

Recently I had to dynamically load some code from a text file and execute it at run time in memory. The CodeDomProvider seemed to do the trick nicely as you can see below. You can generate an assembly in memory using the CompileAssemblyFromSource method like I have done or use it's CompileAssemblyFromFile or CompileAssemblyFromDom counterparts.
using System;
using System.Collections.Generic;
using System.Linq;
 
using Microsoft.CSharp;
using System.CodeDom.Compiler;
 
namespace DynamicCompilerConsoleApp
{
    
    public interface IConsoleWriter
    {
        void WriteToConsole(string message);
    }
    
    public class DynamicAssembyExecution
    {
        public static void DynamicCodeExecution()
        {
            const string code = @"using System;
                                  using DynamicCompilerConsoleApp;
                            namespace LoadXmlTestConsole
                            {
                                public class ConsoleWriter : IConsoleWriter
                                {
                                    public void WriteToConsole(string message)
                                    {
                                        Console.WriteLine(message);
                                    }
                                }
                            }";
 
            CodeDomProvider codeCompiler =
                new CSharpCodeProvider(new Dictionary<stringstring> {{"CompilerVersion""v4.0"}});
            // Create the optional compiler parameters
            CompilerParameters compilerParameters = new CompilerParameters
                                                        {
                                                            GenerateExecutable = false,
                                                            GenerateInMemory = true,
                                                            WarningLevel = 3,
                                                            TreatWarningsAsErrors = false,
                                                            CompilerOptions = "/optimize"
                                                        };
 
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                compilerParameters.ReferencedAssemblies.Add(assembly.Location);    
            }
 
            // Compile the string containing the code, using the provided set of parameters
            CompilerResults compilerResults = codeCompiler.CompileAssemblyFromSource(compilerParameters,
                                                                                        code);
            //Display any compiler errors in the console window
            if (compilerResults.Errors.HasErrors)
                foreach (string line in compilerResults.Output)
                    Console.WriteLine(line);
 
            // Get the required type out of the assembly
            Type consoleWriterType =
                compilerResults.CompiledAssembly.GetTypes().SingleOrDefault(
                    lt => lt.GetInterface(typeof (IConsoleWriter).Name) != null);
              
            // create an instance of the type
            IConsoleWriter consoleWriter = (IConsoleWriter)Activator.CreateInstance(consoleWriterType);
                
            // execute the compiled code
            consoleWriter.WriteToConsole("hello world");
            
        }
    }
}

Wednesday, 14 September 2011

Microsoft Technical Videos/Podcasts

I thought I would share a few video/podcast training resources that I use from time to time.

PDC 2010: http://player.microsoftpdc.com/session
PDC 2009 : http://www.microsoftpdc.com/2009/KEY01
DEVDAYS 2010: http://channel9.msdn.com/Tags/devdays-2010-nl
DEVDAYS 2011: http://channel9.msdn.com/Events/DevDays/DevDays-2011-Netherlands
NDC 2011: http://www.ndc2011.no/agenda.aspx?cat=1071
NDC 2010: http://www.ndc2010.no/agenda.aspx?cat=1071

Silverlight Videos
Silverlight TV : http://channel9.msdn.com/Shows/SilverlightTV

Expression Blend Videos
Expression Blend 4 Videos : http://expression.microsoft.com/en-us/cc197141.aspx

General
Dot Net Rocks TV: http://www.dnrtv.com/
Channel 9: http://channel9.msdn.com/

Podcasts
Dot Net Rocks: http://www.dotnetrocks.com/

Monday, 13 June 2011

Strategy Pattern

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 read 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 "white box" 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.

WCF ProtectionLevel performance test

Normally you should always have your security settings turned on even within an intranet environment.

There are times though when performance is critical and you may want to tweek the relevant WCF security settings.

I thought that I would have a look and see what the effect is of the ProtectionLevel security setting which can be set imperatively or declaratively... so I wrote the following performance test to evaluate the three different possible settings.


using System;
using System.Linq;
using System.ServiceModel;
using System.Net.Security;
using System.Diagnostics;

namespace ProtectionLevel1
{
    //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";

            binding.Security.Mode = SecurityMode.Transport;

            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.Transport.ProtectionLevel = ProtectionLevel.None;

            NetTcpBinding bindingWithSign = new NetTcpBinding();
            bindingWithSign.Security.Transport.ProtectionLevel = ProtectionLevel.Sign;

            NetTcpBinding bindingWithEncryption = new NetTcpBinding();
            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 are 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 improvement when using Protection Level None.

Additional resources:
Understanding Protection Level

Sunday, 12 June 2011

Text search and replace in large files using .net framework

When performing search and replace in large text files you should avoid loading the entire file into memory and rather make use of the StreamReader/StreamWriter classes provided by the .Net Framework. I thought I would share this short code snippet below which makes use of these two useful classes.


using System.IO;
namespace LoadXmlTestConsole
{
    public class TextReplaceConsoleApp
    {
        public static void Main()
        {
            // File to perform search and replace on
            string inputFileLocation = @"D:\largeTextFileInput.xml";

            // File to create with replaced text
            string outputFileLocation = @"D:\largeTextFileOutput.xml";

            using (StreamReader reader = new StreamReader(File.Open(inputFileLocation, FileMode.Open)))
            {
                using (StreamWriter writer = new StreamWriter(File.Open(outputFileLocation, FileMode.Create)))
                {
                    ReplaceInStreams(reader, writer);
                }
            }
        }

        private static void ReplaceInStreams(StreamReader reader, StreamWriter writer)
        {
            while (reader.Peek() != -1)
            {
                string line = reader.ReadLine();
                // If search text found
                if (line.IndexOf("Male") > -1)
                {
                    //Perform text replace on line
                    line = line.Replace("Male", "Alien");
                    writer.WriteLine(line);
                }
                else
                {
                    writer.WriteLine(line);
                }
            }
        }
    }
}

Saturday, 11 June 2011

The importance of simplicity and common sense

I would like to share a short letter I sent to the .NetRocks show many years ago which they read out:

"I find that the two most coveted attributes in a programmer is the appreciation for simple elegant solutions and plain common sense.

It seems as though there are too many of us that enjoy making life unnecessarily complicated within the systems we write/design.

It’s easy to complicate things nowadays with the wide array of abstraction mechanisms we have at our disposal. I always respect programmers/architects that can come up with a simple and scalable solutions. This inevitably pushes the system's complexity into the business rules where it belongs.

Unfortunately, I still find that a lot of programmers/architects make life unnecessarily complicated for the sake of job security. I feel that the one of the most overlooked issues by non-technical/technical management is the responsibility of the programmer (on top of getting the work done on time and within budget) to write self documenting and maintainable code."

END

“I value simplicity over everything; I always look for simplicity.” - Quote from Anders Hejlsberg

Opportunities to reduce technical debt (or delete code) occur when I can identify the following:
a) Code that has been is duplicated, not properly encapsulated into re-usable units.
b) 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) Solutions where there are unnecessary abstractions or layers of indirection.

I do believe that if a software solution is working correctly and extensibility is not an immediate requirement there is no reason to refactor the code. "If it works, don't change it."

Thursday, 9 June 2011

Strong references - Reactive Extensions

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 object's events.

In the example below 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 StrongReferenceTestConsole
{
    class Program
    {

        static void Main(string[] args)
        {
            SampleData sampleData = new SampleData();
            for (int i = 0; i < 3; i++)
            {
                // Create a consumer which registers a method with the sample data objects SampleDataChanged event
                using (Consumer consumer = new Consumer(sampleData))
                {
                    consumer.Name = "Consumer " + i.ToString();

                    //Raise the sample data object's data changed event
                    sampleData.RaiseSampleDataChanged("Work on data - iteration : " + i.ToString());
                }
            }

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

            // Force garbage collection
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Console.ReadLine();
        }

    }

    public class Consumer : IDisposable
    {
        IDisposable _subscription;

        public Consumer(SampleData sampleData)
        {

            // The usual method for event subscription
            //sampleData.SampleDataChanged += new SampleData.SampleDataChangedEventHandler(Consumer_SampleDataChanged);

            //USE RX to subscribe to events
            _subscription = Observable.FromEvent<SampleDataChangedEventArgs>(sampleData, "SampleDataChanged").Subscribe(
                args =>
                Consumer_SampleDataChanged(sampleData, 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");
        }

        #region IDisposable Members

        public void Dispose()
        {
            //UNCOMMENT TO REMOVE MEMORY LEAK - IDisposable is used in Rx to release strong reference.
            //if (_subscription != null) _subscription.Dispose();

            Console.WriteLine("Consumer Dispose");
        }

        #endregion
    }

    /// <summary>
    /// SampleData object which exposes event SampleDataChanged
    /// </summary>
    public class SampleData
    {
        public event EventHandler<SampleDataChangedEventArgs> SampleDataChanged;
        public void RaiseSampleDataChanged(string message)
        {
            if (SampleDataChanged != null)
            {
                Console.WriteLine("SampleDataChanged event has " + SampleDataChanged.GetInvocationList().Count() + " delegates wired up.");

                SampleDataChangedEventArgs e = new SampleDataChangedEventArgs(message);
                SampleDataChanged(this, e);
            }
        }
    }

    public class SampleDataChangedEventArgs : EventArgs
    {
        public SampleDataChangedEventArgs(string message)
        {
            this.Message = message;
        }
        public string Message { get; set; }
    }

}

Console output with memory leak:


Console output without memory leak:

Type discovery in Assemblies using Attributes

I thought I would share a useful class I wrote a long time ago that I used to load a file from the disc, and assuming it was a .Net assembly would identify all the Types in the file which were decorated with a specific attribute.

Unfortunately, and surprisingly the Assembly.ReflectionOnlyLoadFrom(string filename) method also locks files, which was a surprise.... but Jeffry Richter explains the reasoning behind this in his book "CLR via C#". The reason is that the loaded assembly may contain types which derive from types in a different assembly..... So I had to fall back on the strategy of loading the assembly into a temporary application domain, reflect on the assembly and unload the application domain thus unlocking the file and unloading it from memory.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace AssemblyDiscoveryConsole
{
    // The attribute class you are looking for within external assemblies
    public class SomeAttribute : Attribute
    {
    }

    public class TypeFinder
    {
        public string[] LoadTypes(string assemblyFilename)
        {
            AppDomain appDomain = AppDomain.CreateDomain("TypeFinder");
            try
            {
                // Load and query asseblies in domain and return results
                AssemblyReflector ar = (AssemblyReflector)appDomain.CreateInstanceAndUnwrap(
                    typeof(AssemblyReflector).Assembly.FullName,
                    typeof(AssemblyReflector).FullName);
                return ar.LoadTypes(assemblyFilename);
            }
            finally
            {
                // unload the temporary domain
                AppDomain.Unload(appDomain);
            }
        }

        /// <summary>
        /// Class used to load and query assemblies within "TypeFinder" Domain
        /// </summary>
        private class AssemblyReflector : MarshalByRefObject
        {
            private IEnumerable<string> EnumerateTypes(string assemblyFilename)
            {
                Assembly asm = Assembly.LoadFile(assemblyFilename);
                if (asm == null) throw new Exception("Assembly not found");
                foreach (Type t in asm.GetTypes())
                {
                    if (t.GetCustomAttributes(typeof(SomeAttribute), true).FirstOrDefault() != null)
                    {
                        yield return t.AssemblyQualifiedName;
                    }
                }
            }
            public string[] LoadTypes(string assemblyFilename)
            {
                return EnumerateTypes(assemblyFilename).ToArray();
            }
        }
    }
}

IIS7 Site Administration

IIS 7 Site creation and administration has never been easier with the new IIS7 management API. Like the managed Directory services API (System.DirectoryServices.AccountManagement) this library has saved me a lot of time. Here is a code snippet to show you how to create a site, its application, pool and root virtual folder.

Add a reference to the Microsoft.Web.Administration assembly.
Note:
1) Make sure you have IIS7 Features turned on for this library to be available (Windows features).
2) Ensure that you have a reference to System.ServiceModel.
3) Ensure that your target framework is .Net Framework 4.
Location:
C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll

Resources:
http://blogs.msdn.com/b/carlosag/archive/2006/04/17/microsoftwebadministration.aspx
http://learn.iis.net/page.aspx/165/how-to-use-microsoftwebadministration/


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Web.Administration;
using System.IO;
using System.Diagnostics;

namespace IIS7Administration
{
    class Program
    {
        static void Main(string[] args)
        {

            using (ServerManager manager = new ServerManager())
            {

                string siteName = "TestSite";
                string poolName = "TestSitePool";

                try
                {
                    Site site = manager.Sites[siteName];

                    if (site == null)
                    {
                        //create the site
                        site = manager.Sites.CreateElement();
                        site.Id = 1;

                        if (manager.Sites.Count > 0)
                            site.Id = manager.Sites.Max(s => s.Id) + 1;

                        site.ApplicationDefaults.EnabledProtocols = "http,net.tcp";
                        site.SetAttributeValue("name", siteName);
                        manager.Sites.Add(site);

                        // create the site's application
                        Application app = site.Applications.CreateElement();
                        app.SetAttributeValue("path", "/");
                        app.SetAttributeValue("applicationPool", poolName);
                        app.EnabledProtocols = "http,net.tcp";
                        site.Applications.Add(app);

                        // create the sites root virtual directory
                        VirtualDirectory vdir = app.VirtualDirectories.CreateElement();
                        vdir.SetAttributeValue("path", "/");

                        string sitePath = Path.Combine(@"c:\inetpub\wwwroot", siteName);
                        if (!Directory.Exists(sitePath))
                            Directory.CreateDirectory(sitePath);

                        vdir.SetAttributeValue("physicalPath", sitePath);

                        app.VirtualDirectories.Add(vdir);

                    }

                    // Create the default site pool
                    ApplicationPool apppool = manager.ApplicationPools[poolName];

                    // Create the application pool if necessary
                    if (apppool == null)
                    {
                        apppool = manager.ApplicationPools.Add(poolName);
                        Debug.WriteLine("Creating new application pool : " + poolName);
                    }

                    string appPoolUserName = "jean";
                    string appPoolUserPass = "test";

                    // set the pool's identity if necessary
                    apppool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;
                    apppool.ProcessModel.UserName = appPoolUserName;
                    apppool.ProcessModel.Password = appPoolUserPass;

                    // set the pool's runtime version & pipeline mode
                    apppool.ManagedRuntimeVersion = "v4.0";
                    apppool.ManagedPipelineMode = ManagedPipelineMode.Integrated;
                    apppool.AutoStart = true;

                    // setup the bindings for the site
                    Binding httpBinding = (from b in site.Bindings
                                           where b.Protocol == "http"
                                           select b).FirstOrDefault<Binding>();

                    if (httpBinding == null)
                    {
                        httpBinding = site.Bindings.CreateElement();
                        httpBinding.SetAttributeValue("protocol", "http");
                        httpBinding.BindingInformation = "*:" + Convert.ToString("9090") + ":";
                        site.Bindings.Add(httpBinding);
                    }

                    // commit the changes to IIS 7
                    manager.CommitChanges();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Unable to commit changes. Reason:" + ex.Message);
                }
            }

        }
    }
}