Reputation: 4966
Is there any specific example/instance of DI being applied as an architectural principle or design pattern in the .NET Framework itself? Do any (or many) of the types in the framework/BCL conform to IoC?
The type names and a brief illustration/explanation based in C# would be great!
This would compund the need for DI infused design principle as a best-practice...as it is gleaned from the base framework itself.
I reiterate, I am not looking for IoC/DI Frameworks BUT for IoC/DI IN the framework.
EDIT: Just wanted to get more instances/examples ... hence the bounty!
Upvotes: 13
Views: 3162
Reputation: 25734
.NET, especially in a web context, offers Providers to define alternative implementations of framework components. The framework defines an abstract base class, defines one or two concrete implementations on top of it, and allows users to provide their own implementations where desired.
Once defined, the user doesn't control the life-cycle of their implementation. The framework takes over and manages instantiation, setup, and disposal.
Start with System.Configuration.Provider.ProviderBase.
.NET classes that implement ProviderBase:
Examples:
Upvotes: 3
Reputation: 233447
In general there aren't a lot of examples of DI in the BCL - perhaps because the BCL is a rather self-contained framework, and DI is more of an application architecture concern... However, here are some examples I've been able to find so far.
Constructor Injection
There are not many examples of Constructor Injection in the BCL. The best candidates are
Property Injection
We also see a variation in Workflow Foundation's WorkflowRuntime.AddService
and related methods, although you might argue that this is closer to Method Injection.
Method Injection
Ambient Context
FWIW, I drew these examples from my upcoming book.
Upvotes: 16
Reputation: 66783
This is an example of how you can create a System.ComponentModel.Composition.Hosting.CompositionContainer in .NET 4:
var exeCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
var dircatalog = new DirectoryCatalog(".");
var aggregateCatalog = new AggregateCatalog(exeCatalog, dirCatalog);
var exportProvider = new CatalogExportProvider(aggregateCatalog);
var container = new CompositionContainer(exportProvider);
This is an example of dependency injection via constructor arguments. Because the dependency injection pattern was followed, these classes are very extensible: you can write your own ComposablePartCatalog
implementation and pass that to the export provider constructor. Or you can bypass the whole concept of part catalogs and write your own ExportProvider
implementation.
(Incidentally, CompostionContainer
is itself part of an IoC framework, but that's not the point of this example.)
Upvotes: 4
Reputation: 122684
Sure - the IServiceProvider interface has been part of the Framework since 1.0. This isn't DI as it is typically discussed here (using a "kernel"), but it is IoC using the Service Locator pattern.
If you dig into any of the Windows Forms Designer code, you'll see it peppered liberally with lines like this one:
IDesignerOptionService service =
(IDesignerOptionService)this.GetService(typeof(IDesignerOptionService));
If you're working with a Component, then you get access to this via the Site property. It's quite common and practically required knowledge when creating custom controls.
This is Service Location, textbook example. You've got a generic IServiceProvider
that hands out abstract services you request by service type. If you ever want to create custom designers - smart tags and so on - then you need to know all of this. It's similar for ASP.NET as well.
P.S. Please don't use IServiceProvider
in new code. It's a very old, non-generic interface. If you are creating reusable libraries that require an IoC container in order to work, you should use the Common Service Locator instead. But don't even use that unless you absolutely require that your library be agnostic of the DI library used at the application tier; most of the implementation-specific containers/kernels offer much richer APIs that you'll miss out on if you nail yourself to the CSL.
Upvotes: 5
Reputation: 84835
I am currently reading the book The Art of Unit Testing by Roy Osherove. He mentions a technique called Extract and Overload (that is, injecting a dependency into a class through overriding a virtual method that is responsible for returning the dependency).
I think I've come across various instances of that technique, for example these:
Customizing the ADO.NET type DataTable
:
If you derive from DataTable
, you have the possibility of overriding various methods, such as GetRowType()
, CreateInstance()
, and others.
Customizing Workflow Foundation Activity designers (in .NET 3.5)
I don't remember the exact class, but I think if you want to create custom activity designs, you derive new classes from existing ones, and the pattern is much the same; you override a virtual method which allows you to return your custom dependency to the framework.
Upvotes: 2
Reputation: 245489
Both the StreamReader and StreamWriter could be seen as examples of IoC/DI.
Each allow you to inject a different Stream object (or one of its derivatives) for reading/writing respectively.
FileInfo fi = new FileInfo(@"C:\MyFile.dat");
StreamWriter sw = new StreamWriter(fi.Open());
Or:
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
Would both allow:
sw.Write("Hello world!");
The same way, no matter what kind of Stream you injected in the call to the constructor.
Upvotes: 12