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;
}
}
}
Like this:
Like Loading...
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.
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.
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!.
Well done, nice article. very nice to see the walk through in a very clean and straight forward method.
Thank you. Neat explanation. I have understood clearly after reading your article.