5

i'm trying to find an example in .NET of a class that uses Dependancy Injection (e.g. a class that uses a Builder or Factory in order to create the full object - injecting dependencies as it does)

Browsing through Reflector, i would have thought some of the more complicated ado.net or WebRequest objects would use dependency injection - but no.

Can anyone point to an example inside the .NET framework of an object that uses dependency injection to get its work done?

Ian Boyd
  • 220,884
  • 228
  • 805
  • 1,125
  • 1
    it seems that you're confused as to what dependency injection really is. – Mauricio Scheffer Oct 04 '10 at 14:11
  • @Mauricio Scheffer Probably; which is why i'm hoping to find a class in the .NET framework that uses it. That will be the perfect real-world example case to help me understand it. – Ian Boyd Oct 04 '10 at 14:35
  • 2
    This link will help you understand DI more than some .NET FX class will do: http://stackoverflow.com/questions/130794/what-is-dependency-injection. – Steven Oct 04 '10 at 15:24
  • Yeah, i'd still like a practical example. – Ian Boyd Oct 04 '10 at 17:26
  • 1
    The .NET framework doesn't use dependency injection for a number of reasons. The biggest is that because it's a framework, it should not impose any kind of architectural model on the applications that use it. In addition, the framework tends to be discrete objects that are often reused and extended by applications. There aren't a lot of good candidates for DI in the framework, so they choose consistency and do everything the same way. – Erik Funkenbusch Oct 04 '10 at 17:31
  • Mystere Man: Spring is a framework that uses dependency injection. – Bernard Oct 04 '10 at 17:39
  • Just because various frameworks do things, doesn't mean they SHOULD be doing those things. Frameworks should not impose such things on their applications. Unless of course, they're a dependency injection framework themselves, which is basically what spring is at it's core. All the other stuff is built on it's core DI framework. – Erik Funkenbusch Oct 04 '10 at 17:54
  • @Mystere Man - why does the use of DI in a framework force its use on the consumer of that framework? Just because an underlying framework relies upon runtime resolution to inject dependencies doesn't mean the application sitting on it does. – Michael Shimmins Oct 05 '10 at 02:14
  • i should also say that i don't require an example where **i** have to inject dependencies into a .NET object. If a class in the .NET framework wants to use dependency injection - that's an internal implementation detail - that can, and should, be hidden from me. But since we can go peeking at implementation details: it's not really hidden. But of course the classes public facing methods and constructors wouldn't indicate the use of DI. – Ian Boyd Oct 05 '10 at 03:44
  • @Michael Shimmins - While true, to a point, a framework is something that applications base themselves on, and it's a rare fraemwork that doesn't let it's implementation details influence its API – Erik Funkenbusch Oct 05 '10 at 18:57

4 Answers4

3

There is a lot of places in the .NET Framework that uses Dependency Injection. First of all, .NET Framework uses a lot of GoF patterns and some of them heavily relies on Dependency Injection. For example, Decorator Design Pattern always uses Constructor Injection and Strategy Design Pattern uses Constructor Injection or Method Injection:

// Decorator on Streams (uses Constructor Injection)
var ms = new MemoryStream();
var bs = new BufferedStream(ms);

// Strategy of sorting (uses Method Injection)
var list = new List<int>();
list.Sort(new CustomComparer());

// Strategy of sorting (Constructor Injection)
var sortedArray = new SortedList<int, string>(
                        new CustomComparer());

// Strategy of starting new task using TaskScheduler
// (Method Injection)
var task = Task.Factory.StartNew(
    () => { }, 
    CancellationToken.None, 
    TaskCreationOptions.None, 
    TaskScheduler.Default);

    // All method that takes IFormatProvider and
    // similar strategies is an example of the Method Injection
    IFormatProvider provider = null;
    42.ToString(provider);

Any usage of Abstract Factory Design Pattern means that you're going to "inject" factory object using Constructor Injection or Method Injection and there is a plenty of examples in .NET Framework of this pattern like DbProviderFactory.

To get more example that will show what BCL types are uses Constructor Injection, I've written a simple LINQ query (I'll show it later) that enumerate all accessible types to find types with a public constructor that accepts an interface or abstract type as a parameter. This query showed many other usages of Constructor Injection in .NET Framework (here some examples):

// ResourceReader takes a Stream
Stream ms = new MemoryStream();
var resourceReader = new ResourceReader(ms);

// BinaryReader/BinaryWriter, StreamReader/StreamWriter
// takes a Stream as well
var textReader = new StreamReader(ms);

// MethodCall takes a IMessage
IMessage message = new System.Runtime.Remoting.Messaging.MethodResponse(null, null);
var methodCall = new System.Runtime.Remoting.Messaging.MethodCall(message);

// Icon takes a Stream
var icon = new System.Drawing.Icon(ms);

// DbEnumerator takes a IDataReader
IDataReader dataReader = new DataTableReader(new DataTable());
var dbEnumerator = new System.Data.Common.DbEnumerator(dataReader);

This is only limited list of types and .NET Framework contains many more types that relies on this technique. Constructor Injection was widely used technique long before this term emerged, so I don't surprised that this is so widely used. You can use following LINQ-query to obtain many more other samples of constructor injection (and with slight modification you can write a query that will find Method Injection patterns):

var types =
    AppDomain.CurrentDomain.GetAssemblies()
        .SelectMany(a => a.GetTypes())
        .SelectMany(t => t.GetConstructors()
                                .Where(c => c.GetParameters()
                                                .Any(cp =>
                                                    (cp.ParameterType.IsAbstract ||
                                                    cp.ParameterType.IsInterface))))

        .Select(ci => new {Type = ci.DeclaringType, Constructor = ci.GetConstructorInfo()})
        .Where(t => !t.Type.Namespace.Contains("Internal"));
Sergey Teplyakov
  • 10,737
  • 29
  • 45
3

Here are a couple of examples of dependency injection in the framework:

WCF's ChannelDispatcher has constructor injection (mandatory dependency) of IChannelListener. In general though, WCF relies on configuration to do user-level injection of optional dependencies.

System.Xml does poor-man's dependency injection in a number of places. For example, XmlDocument has a constructor injection (internal) on XmlImplementation. The default constructor just instantiates the needed XmlImplementation. XmlImplementation itself depends on XmlNameTable. XmlResolvers are another example of injection.

MEF's CompositionContainer optionally depends on a ComposablePartCatalog and ExportProviders. ImportEngine has constructor injection of ExportProvider

ASP.NET MVC's Controller has setter injection on IActionInvoker and ITempDataProvider (they have default implementations) Model binders are also injectable.

If you're just starting out with dependency injection, IMHO the .NET framework is the worst place you can learn from: most of the time you won't have the source code, it's framework-level (not application-level) code with quite special requirements. In particular Microsoft is very careful to make things public (default is internal), as opposed to most open source projects, in order to better manage their breaking changes.

Mauricio Scheffer
  • 96,120
  • 20
  • 187
  • 273
1

I think there's DI littered all over the .NET Framework, but it's a special form of DI called "Property Injection" -- in the Java world it's frequently called "Setter Injection".

Randolpho
  • 52,575
  • 15
  • 139
  • 173
0

Here's a real simple (silly) example of Dependency Injection via a Factory:

public class MyService1Factory {
    public IMyService1 Create() {
        MyService2 service = new MyService2();
        // provides dependent IMyService2 for MyService
        return new MyService(service);
    }
}

public class MyService : IMyService1 {
    private IMyService2 service;

    // MyService depends upon IMyService2, an instance of this "dependency" is 
    // passed in (or "injected") via a simple constructor param
    public MyService(IMyService2 myService2) {
        service = myService2;
    }
}
Max
  • 626
  • 6
  • 10