Archive

Posts Tagged ‘Gang Of Four’

Covariance in C#

February 28, 2011 1 comment

We are going to have a quick look at covariance in C#.

Only elements that can be covariant:

  • Interfaces
  • Delegates

Convariance is similar to Inheritance in the sense that if you have a class like IEnumerable which is covariant then you can assign a subclass of IEnumerable to IEnumerable.

Example: Base Person, Sub Class is Student. With Covariance you can assign IEnumerable to IEnumerable

You would just naturally think this would work but is has not until .NET 4 was introduced.

To allow convariance you must mark the generic parameter as out T as shown below in IIterable and IIterator. I wrote my own iterator design pattern based classes below to illustrate this.

you can only assign using references as shown in the main method. Assigning to base classes not interfaces won’t work.

using System;
using System.Collections.Generic;

namespace Variance
{


    public abstract class Entity<TKey> : IEquatable<Entity<TKey>>
    {

        public TKey Id { get; set; }

        protected Entity()
        {
            Id = default(TKey);
        }

        protected Entity(TKey identity)
        {
            Id = identity;
        }

        public override bool Equals(object obj)
        {
            var entity = obj as Entity<TKey>;
            return Equals(entity);
        }

        public bool Equals(Entity<TKey> other)
        {
            return other != null && Equals(Id, other.Id);
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }
    }

    public class Person : Entity<int>
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return String.Format("{0} - {1}", Id, Name);
        }
    }

    public class Student : Person
    {
        public string Course { get; set; }
    }

    public interface IIterator<out T>
    {
        bool HasMoreElements { get; }
        T Current { get; }
        void Continue();
    }

    public interface IIterable<out T>
    {
        IIterator<T> GetIterator();
    }

    public class BasicList<T> : IIterable<T>
    {

        protected List<T> Items = new List<T>();

        public void AddItem(T item)
        {
            Items.Add(item);
        }

        public IIterator<T> GetIterator()
        {
            return new BlIterator<T>(Items);
        }

        public void PrinttoConsole()
        {
            foreach (var item in Items)
            {
                Console.WriteLine(item);
            }
        }

        public class BlIterator<T> : IIterator<T>
        {

            protected List<T> items = new List<T>(); 

            public BlIterator(List<T> items)
            {
                this.items = items;
            }

            private int index;

            public bool HasMoreElements
            {
                get { return index <= items.Count - 1; }
            }

            public T Current
            {
                get { return items[index]; }
            }

            public void Continue()
            {
                index++;
            }
        }


    }

    class Program
    {

        

        static void Main()
        {

            IIterable<Student> students = GetStudents();

            Print(students); // Covariance



            IIterable<Person> people = students; // Covariance

            Print(people);

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }

        public static IIterable<Student> GetStudents()
        {
            BasicList<Student> students = new BasicList<Student>();
            students.AddItem(new Student { Id = 1, Name = "Blair" });
            students.AddItem(new Student { Id = 2, Name = "Tim" });
            students.AddItem(new Student { Id = 3, Name = "Tom" });
            return students;
        }

        public static void Print(IIterable<Person> print) // Covariance
        {

            var iterator = print.GetIterator();

            while (iterator.HasMoreElements)
            {
                Console.WriteLine(iterator.Current);
                iterator.Continue();
            }
        }
    }
}

Blair…

Adding Behaviors to ActionResults

January 28, 2011 Leave a comment

One problem you have with MVC is that you often need to tweak action response and add additional functionally to them. One solution is to sub class. The issues here you end up with a mess of classes and a deep inheritance tree. One solution decorator pattern.

public class ActionResultDecorator : ActionResult
    {

        protected ActionResult WrappedAction { get; private set; }

        public ActionResultDecorator(ActionResult wrappedActionResult)
        {
            WrappedAction = wrappedActionResult;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            WrappedAction.ExecuteResult(context);
        }
    }

     public class MimeTypeActionResultDecorator : ActionResultDecorator
    {

        public string MimeType { get; set; }

        public MimeTypeActionResultDecorator(ActionResult wrappedActionResult)
            : base(wrappedActionResult)
        {
        }

        public override void ExecuteResult(ControllerContext context)
        {
            context.HttpContext.Response.ContentType = MimeType;
            base.ExecuteResult(context);
        }
    }


Simple solution like a Russian doll.

Blair

Creating MVC Controller Factories with Windsor

December 14, 2010 Leave a comment

You can setup dependency injection just by implementing the IControllerFactory interface or inheriting from DefaultControllerFactory. Default controller factory is preferred as it takes care of providing you more than just a controller name like Customer. Doing this manually is not great as you can see from the example below.

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Routing;
using System.Linq;

namespace MVCSamples.Infrastructure
{
    public class WindsorControllerFactory : IControllerFactory
    {

        private IEnumerable<Type> _controllerTypes;

        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            BuildDefaultControllerTypes();
            return IoC.Resolve(GetTypeNameForController(controllerName)) as IController;
        }

        public void BuildDefaultControllerTypes()
        {
            if (_controllerTypes == null || !_controllerTypes.Any())
                _controllerTypes = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.Name.EndsWith("Controller")).ToList();
        }

        public string GetTypeNameForController(string controllername)
        {
            return _controllerTypes.First(x => x.Name == String.Format("{0}Controller", controllername)).FullName;
        }

        public void ReleaseController(IController controller)
        {
            var disposablecontroller = controller as IDisposable;
            if (disposablecontroller != null) disposablecontroller.Dispose();
            IoC.Release(controller);
        }
    }
}

The second implementation below is not so naive. The DefaultControllerFactory takes care of finding the controller type for you. Just override the GetControllerInstance Method.

using System;
using System.Web.Mvc;

namespace MVCSamples.Infrastructure
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {

        protected override IController GetControllerInstance(Type controllerType)
        {
            return IoC.Resolve(controllerType) as IController;
        }

        public override void ReleaseController(IController controller)
        {
            var disposablecontroller = controller as IDisposable;
            if (disposablecontroller != null) disposablecontroller.Dispose();
            IoC.Release(controller);
        }
    }
}

Blair

StructureMap Registries

October 28, 2010 Leave a comment

Registries allow you to extract the code you use to register components into different locations. Why is this important. Well I use always use a bootstrapper in my applications to load all the types for me. Now I can have each assembly if applicable define a registry of how to mapping in their own assembly.

Lets look at an example.

using System;
using System.Reflection;
using StructureMap;
using StructureMap.Configuration.DSL;

namespace StructureMapExamples
{

    public class EntityBase
    {
        public Guid Id { get; set; }
    }

    public class AggregateRoot : EntityBase { }

    public interface IRepository<TEntity>
        where TEntity : AggregateRoot
    {
        void Save(TEntity entity);
        void Update(TEntity entity);
        void Delete(TEntity entity);
        Guid Get(int id);
    }

    public class Customer : AggregateRoot
    {
        private string _name;

        public Customer(string name)
        {
            _name = name;
        }

        public void AssignName(string name)
        {
            _name = name;
        }
    }

    public class RepositoryBase<TEntity> : IRepository<TEntity>
        where TEntity : AggregateRoot
    {
        public void Save(TEntity entity)
        {
            Console.WriteLine("Saving TEntity: {0}", entity);
        }

        public void Update(TEntity entity)
        {
            Console.WriteLine("Update TEntity: {0}", entity);
        }

        public void Delete(TEntity entity)
        {
            Console.WriteLine("Delete TEntity: {0}", entity);
        }

        public Guid Get(int id)
        {
            Console.WriteLine("Getting TEntity: {0}", id);
            return Guid.Empty;
        }
    }

    public interface ICustomerRepository : IRepository<Customer>
    {

    }

    public class CustomerRepository : RepositoryBase<Customer>, ICustomerRepository
    {

        
    }

    public static class Bootstrapper
    {
        public static void WireUp(IContainer container)
        {
            container.Configure(x => x.Scan(y =>
                                                {

                                                    y.TheCallingAssembly();
                                                    y.LookForRegistries();

                                                }));   
        }
    }

    public class ExampleRegistry : Registry
    {
        public ExampleRegistry()
        {
            For<ICustomerRepository>().Use<CustomerRepository>();
        }
    }

    public class Program
    {

        static void Main(string[] args)
        {
            Program program = new Program();
            program.InitializeContainer();
            program.PrintWhatHasBeenRegisteredInStructureMap();

            Console.WriteLine("Press any key to quit");
            Console.ReadKey();
        }

        public void InitializeContainer()
        {
            Bootstrapper.WireUp(ObjectFactory.Container);
        }

        public void PrintWhatHasBeenRegisteredInStructureMap()
        {
            Console.WriteLine(ObjectFactory.WhatDoIHave());
        }

    }
}


The bootstrapper scans all assemblies for there registries and each registry know how to do their little bit of registration.

Blair..

StructureMap Automatic Registration Via Scanning – Part 1

October 28, 2010 Leave a comment

After looking at the previous examples you could imagine if you had a large project this would be a bit of a pain manually.
We can get StructureMap to automatically wire up most of this stuff for us. For example we can get StructureMap to Scan the assembly using the Scan method and wire up concrete class to their interfaces automatically. This maybe to basic for you and we will explorer more advanced usages in other sessions.

using System;
using System.Reflection;
using StructureMap;

namespace StructureMapSamples
{

    public class EntityBase
    {
        public Guid Id { get; set; }
    }

    public class AggregateRoot : EntityBase { }

    public interface IRepository<TEntity>
        where TEntity : AggregateRoot
    {
        void Save(TEntity entity);
        void Update(TEntity entity);
        void Delete(TEntity entity);
        Guid Get(int id);
    }

    public class Customer : AggregateRoot
    {
        private string _name;

        public Customer(string name)
        {
            _name = name;
        }

        public void AssignName(string name)
        {
            _name = name;
        }
    }

    public interface ICustomerRepository : IRepository<Customer>
    {

    }

    public class CustomerRepository : ICustomerRepository
    {

        public void Save(Customer entity)
        {
            Console.WriteLine("Saving Customer: {0}", entity);
        }

        public void Update(Customer entity)
        {
            Console.WriteLine("Update Customer: {0}", entity);
        }

        public void Delete(Customer entity)
        {
            Console.WriteLine("Delete Customer: {0}", entity);
        }

        public Guid Get(int id)
        {
            Console.WriteLine("Getting Customer: {0}", id);
            return Guid.Empty;
        }
    }

    public class Program
    {


        static void Main(string[] args)
        {
            Program program = new Program();
            program.InitializeContainer();
            program.PrintWhatHasBeenRegisteredInStructureMap();

            Console.WriteLine("Press any key to quit");
            Console.ReadKey();
        }

        public void InitializeContainer()
        {
            ObjectFactory.Configure(
                    x => x.Scan(
                            y =>
                            {
                                y.WithDefaultConventions();
                                y.Assembly(Assembly.GetExecutingAssembly());
                            }

                        )
                );
        }

        public void PrintWhatHasBeenRegisteredInStructureMap()
        {
            Console.WriteLine(ObjectFactory.WhatDoIHave());
        }


    }
}

The with defaults conventions does the automatic concrete class to interface map as mentioned before.

Hope this helps.
Blair

StructureMap Basic Debugging

October 28, 2010 Leave a comment

Following on from the last post. We will look at the example and see how we can get a print out of what has been registered. This is really useful if you are having issues and need to see what StructureMap is actually doing.

To see what has been registered check out the WhatDoIHave method on the ObjectFactory Class.

Here is the source code with the new functionality.

using System;
using StructureMap;

namespace StructureMapSamples
{
    public interface ILogger
    {
        void Log(string message);
    }

    public class RemoteLogger : ILogger
    {
        private readonly string _server;

        public int Port { get; set; }

        public RemoteLogger(string server)
        {
            _server = server;
            Port = 80;
        }

        public void Log(string message)
        {
            Console.WriteLine("Writing {0} to {1}:{2}", message,_server,Port);
        }
    }

    public class Program
    {
        

        static void Main(string[] args)
        {
            Program program = new Program();
            program.InitializeContainer();
            program.PrintWhatHasBeenRegisteredInStructureMap();
            program.RunExamplesWithCtorArgsPassedToTypeAndPropertyValuesSet();

            Console.WriteLine("Press any key to quit");
            Console.ReadKey();
        }

        public void InitializeContainer()
        {
            ObjectFactory.Configure(
                    x => x.For<ILogger>()
                          .Use<RemoteLogger>()
                          .Ctor<string>("server").Is("www.google.com")
                          .SetProperty(y => y.Port = 8080)
                );
        }

        public void PrintWhatHasBeenRegisteredInStructureMap()
        {
            Console.WriteLine(ObjectFactory.WhatDoIHave());
        }

        private void RunExamplesWithCtorArgsPassedToTypeAndPropertyValuesSet()
        {
            ILogger logger = ObjectFactory.GetInstance<ILogger>();
            logger.Log("Hello Google");
        }
    }
}

Also here is what the output from this method looks like.
================================================================================
===========================
Configuration Sources:

================================================================================
================================================================================
======================================================
PluginType Name
Description

——————————————————————————–
——————————————————————————–
——————————————————
Func`1 (Func`1)

Scoped as: Transient

15469a1d-2e3d-45d8-a850-e2eb37ea9187

——————————————————————————–
——————————————————————————–
——————————————————
IContainer (StructureMap.IContainer) 8d3565d0-8c7e-4bb2-8bea-9febbaf37fcd
Object: StructureMap.Container

Scoped as: Transient

8d3565d0-8c7e-4bb2-8bea-9febbaf37fcd
Object: StructureMap.Container

——————————————————————————–
——————————————————————————–
——————————————————
ILogger (StructureMapSamples.ILogger) 1abf6438-9b9a-4519-8651-51bd5dda1c69
Configured Instance of StructureMapSamples.RemoteLogger, StructureMapSamples,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Scoped as: Transient

1abf6438-9b9a-4519-8651-51bd5dda1c69
Configured Instance of StructureMapSamples.RemoteLogger, StructureMapSamples,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
================================================================================
================================================================================
======================================================
Writing Hello Google to http://www.google.com:8080
Press any key to quit

Hope this helps.

Blair

StructureMap Manual Registration – Setting Properties

October 28, 2010 Leave a comment

Hi all back again with another example of using structure map manually. Were going to follow on from the last example.

If you have a concrete type that need a property set then you use the SetProperty Method and use an action lambda statement like below to set it up. EASY.

Pretty easy hey.

using System;
using StructureMap;

namespace StructureMapSamples
{
    public interface ILogger
    {
        void Log(string message);
    }

    public class RemoteLogger : ILogger
    {
        private readonly string _server;

        public int Port { get; set; }

        public RemoteLogger(string server)
        {
            _server = server;
            Port = 80;
        }

        public void Log(string message)
        {
            Console.WriteLine("Writing {0} to {1}:{2}", message,_server,Port);
        }
    }

    public class Program
    {
        

        static void Main(string[] args)
        {
            Program program = new Program();
            program.InitializeContainer();
            program.RunExamplesWithCtorArgsPassedToTypeAndPropertyValuesSet();

            Console.WriteLine("Press any key to quit");
            Console.ReadKey();
        }

        public void InitializeContainer()
        {
            ObjectFactory.Configure(
                    x => x.For<ILogger>()
                          .Use<RemoteLogger>()
                          .Ctor<string>("server").Is("www.google.com")
                          .SetProperty(y => y.Port = 8080)
                );
        }

        private void RunExamplesWithCtorArgsPassedToTypeAndPropertyValuesSet()
        {
            ILogger logger = ObjectFactory.GetInstance<ILogger>();
            logger.Log("Hello Google");
        }
    }
}

Hope this helps.

Blair