Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

No more factories in C#

0.00/5 (No votes)
4 Nov 2013 1  
No more factories in C#.

Introduction

Using IoC we can rely on it to provide instances we need for our contracts.

Background

This is kind of a respond to my previous Tip where people mentioned is better to use IoC instead of having a factory. I do think it is better but not in all situations our project can afford using a a IoC library, (e.g. compact or micro framework) or we currently do not have IoC implemented in our project and others I cannot think of.

Using the code

IoC implementation choosen is Ninject.

Below is the class diagram, we have an abstract class and three implementations.

Below abstract class, it contains constanst that will help us identify our concrete class.

  public abstract class MyContractBase
  {
    public abstract void MyMethod();
    
    public static string ConcreteClass1 { get { return "MyConcreteImplementation1";}}
    public static string ConcreteClass2 { get { return "MyConcreteImplementation2";}}
    public static string ConcreteClass3 { get { return "MyConcreteImplementation3";}}
  }

A simple Service Locator class it used to wrap Ninject. I have heard about people thinking this is an anti pattern but so far it has more benefits than drawbacks.

  public static class IoCContainer
  {
    static IoCContainer()
    {
      _Kernel = new StandardKernel();
    }
    public static void LoadModules(params INinjectModule[] modules)
    {
      _Kernel.Load(modules);
    }
    public static T GetService<T>()
    {
      return _Kernel.Get<T>();
    }
    public static T GetService<T>(string name)
    {
      return _Kernel.Get<T>(name);
    }
    static readonly IKernel _Kernel;
  } 

Then we have a class that registers our bindings. We have in our base class constants that we use to uniquely identify our concrete types.

  public class ComponentInstaller : NinjectModule
  {
    public override void Load()
    {
      Bind<MyContractBase>().To<MyConcreteClass1>().Named(MyContractBase.ConcreteClass1);
      Bind<MyContractBase>().To<MyConcreteClass2>().Named(MyContractBase.ConcreteClass2);
      Bind<MyContractBase>().To<MyConcreteClass3>().Named(MyContractBase.ConcreteClass3);
    }
  }  

That's pretty much it. We only need let IoC container that this class will be in charge of component registrarion and rest of the work will be done by Ninject.

Below Unit test included in the code shows and example.

     [TestMethod]
    public void TestInstancesCreatedByIoCContainer()
    {
      IoCContainer.LoadModules(new ComponentInstaller());
      MyContractBase myContractBase = IoCContainer.GetService<MyContractBase>(MyContractBase.ConcreteClass1);
      Assert.IsInstanceOfType(myContractBase, typeof(MyConcreteClass1));
      myContractBase = IoCContainer.GetService<MyContractBase>(MyContractBase.ConcreteClass2);
      Assert.IsInstanceOfType(myContractBase, typeof(MyConcreteClass2));
      myContractBase = IoCContainer.GetService<MyContractBase>(MyContractBase.ConcreteClass3);
      Assert.IsInstanceOfType(myContractBase, typeof(MyConcreteClass3));
    }
  } 

Points of Interest

Either way you go using custom factories in your code or relying on IoC, the goal is to decouple. Having somewhere else knowledge of concrete type that should be created.

I expect this gives another approach and can be useful to someone.

Any comment please bring them on.

Code attached was created in VS2012 it targets framework 3.5.   

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here