Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Framework object that uses Dependency Injection?

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?

like image 336
Ian Boyd Avatar asked Oct 04 '10 13:10

Ian Boyd


2 Answers

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.

like image 124
Mauricio Scheffer Avatar answered Sep 22 '22 17:09

Mauricio Scheffer


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"));
like image 41
Sergey Teplyakov Avatar answered Sep 22 '22 17:09

Sergey Teplyakov