Rich Newman

Dependency Injection Example: Interface Injection

using System;

namespace DependencyInjection
{
    public interface IDependentClass
    {
        void DoSomethingInDependentClass();
    }

    public interface IInjectDependent
    {
        void InjectDependent(IDependentClass dependentClass);
    }

    public class MainClass : IInjectDependent
    {
        IDependentClass dependentClass;

        public void DoSomething()
        {
            dependentClass.DoSomethingInDependentClass();
        }

        #region IInjectDependent Members

        public void InjectDependent(IDependentClass dependentClass)
        {
            this.dependentClass = dependentClass;
        }

        #endregion
    }

    public class DependentClass1 : IDependentClass
    {
        public void DoSomethingInDependentClass()
        {
            Console.WriteLine("Hello from DependentClass1: I can be injected into MainClass");
        }
    }

    public class DependentClass2 : IDependentClass
    {
        public void DoSomethingInDependentClass()
        {
            Console.WriteLine("Hello from DependentClass2: I can be injected as well, just change App.Config");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Get the correct dependency based on configuration file
            IDependentClass dependency = GetCorrectDependency();

            // Create our main class and inject the dependency
            MainClass mainClass = new MainClass();
            ((IInjectDependent)mainClass).InjectDependent(dependency);

            // Use the main class, the method references the dependency
            // so behaviour depends on the configuration file
            mainClass.DoSomething();

            Console.ReadLine();
        }

        /// <summary>
        /// Instantiate and return a class conforming to the IDependentClass interface:
        /// which class gets instantiated depends on the ClassName setting in
        /// the configuration file
        /// </summary>
        /// <returns>Class conforming to the IDependentClass interface</returns>
        static IDependentClass GetCorrectDependency()
        {
            string classToCreate = System.Configuration.ConfigurationManager.AppSettings["ClassName"];
            Type type = System.Type.GetType(classToCreate);
            IDependentClass dependency = (IDependentClass)Activator.CreateInstance(type);
            return dependency;
        }
    }
}

6 Comments »

  1. This is one of the most concise explanation on DI.

    I have read Martin Fowler’s original version. However, it was not easy to grasp. Your version was able to enlighten me on the subject.

    Comment by Ken — August 13, 2009 @ 7:50 pm

  2. I wonder if it is possible to “inject an interface *implementation*” as well. By this I do not mean to generate a new type that implements some interface (which is certainly doable), but to modify an existing (precomiled) type at run-time so it supports an interface?

    I want this in order to enable me to generate data access code dynamically and allow this code to access the private fields of entity classes (read them when saving, write them when loading).

    In other words, I want an entity class to change from something like

    public class Toto : Entity
    {
    int n;
    Toto parent;
    //… non-field members
    }

    at run-time into something like

    public class Toto : Entity, IFieldAccessible
    {
    int n;
    Toto parent;
    //… non-field members
    object[] IFieldAccessible.GetFieldValues()
    {
    return new object[] { n, parent };
    }

    void IFieldAccessible.SetFieldValues(object[] values)
    {
    n = (int)values[0];
    parent = (Toto)values[1];
    }
    }

    I can generate the implementation by using reflection to discover the fields, but I need it to be somehow embedded into the type itself since otherwise I cannot access the fields without using reflection on every instance, which is comparatively slow.

    Comment by Dag Johansen — November 4, 2009 @ 1:17 pm

  3. Thanks!. I too searched the whole web for a meaningful explanation but either it was over the head-too abstract or too flimsy in explanation.Again thanks!.

    Comment by cba chellam — September 17, 2010 @ 9:53 am

  4. Well done, nice article. very nice to see the walk through in a very clean and straight forward method.

    Comment by bryan strader — February 23, 2011 @ 12:20 am

  5. [...] injection is a pattern that doesn’t need a 3rd party framework to implement, for instance this is an example of dependency injection (interface injection specifically) sans a framework in C#.  Frameworks [...]

    Pingback by Inversion of Control and Dependency Injection | In the trenches — October 8, 2011 @ 9:27 pm

  6. […] 依赖注入有以下几种实现方式: 1、接口注入或叫Type 1型注入。需要实现特定接口以供外部容器注入所依赖类型的对象。这里有一个写的比较好的例子。这种注入方式很少用到。 2、setter注入或叫Type 2型注入。实现特定属性的public set方法,来让外部容器调用传入所依赖类型的对象。这种注入方式是最常见的。 3、构造函数注入或叫Type 3型注入。实现特定参数的构造函数,在新建对象时传入所依赖类型的对象。 4、注解注入。基于Java的注解功能,在私有变量前加“@Autowired”等注解,不需要显式的定义以上三种代码,便可以让外部容器传入对应的对象。该方案相当于定义了public的set方法,但是因为没有真正的set方法,从而不会为了实现依赖注入导致暴露了不该暴露的接口(因为set方法只想让容器访问来注入而并不希望其他依赖此类的对象访问)。注解注入是比较好的注入实现方式。 […]

    Pingback by 依赖倒置(DIP),控制反转(IoC)与依赖注入(DI) | OpenWares | Open Source and Free Matters — October 8, 2013 @ 8:49 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 80 other followers

%d bloggers like this: