Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The term "dependency injection" doesn't specifically have anything to do with an IoC container at all, even though you tend to see them mentioned together. It simply means that instead of writing your code like this:</p> <pre><code>public class Service { public Service() { } public void DoSomething() { SqlConnection connection = new SqlConnection("some connection string"); WindowsIdentity identity = WindowsIdentity.GetCurrent(); // Do something with connection and identity variables } } </code></pre> <p>You write it like this:</p> <pre><code>public class Service { public Service(IDbConnection connection, IIdentity identity) { this.Connection = connection; this.Identity = identity; } public void DoSomething() { // Do something with Connection and Identity properties } protected IDbConnection Connection { get; private set; } protected IIdentity Identity { get; private set; } } </code></pre> <p>That is, you do two things when you write your code:</p> <ol> <li><p>Rely on interfaces instead of classes whenever you think that the implementation might need to be changed;</p></li> <li><p>Instead of creating instances of these interfaces inside a class, pass them as constructor arguments (alternatively, they could be assigned to public properties; the former is <em>constructor injection</em>, the latter is <em>property injection</em>).</p></li> </ol> <p>None of this presupposes the existence of any DI library, and it doesn't really make the code any more difficult to write without one.</p> <p>If you're looking for an example of this, look no further than the .NET Framework itself:</p> <ul> <li><p><code>List&lt;T&gt;</code> implements <code>IList&lt;T&gt;</code>. If you design your class to use <code>IList&lt;T&gt;</code> (or <code>IEnumerable&lt;T&gt;</code>), you can take advantage of concepts like lazy-loading, as Linq to SQL, Linq to Entities, and NHibernate all do behind the scenes, usually through property injection. Some framework classes actually accept an <code>IList&lt;T&gt;</code> as a constructor argument, such as <code>BindingList&lt;T&gt;</code>, which is used for several data binding features.</p></li> <li><p>Linq to SQL and EF are built entirely around the <code>IDbConnection</code> and related interfaces, which can be passed in via the public constructors. You don't need to use them, though; the default constructors work just fine with a connection string sitting in a configuration file somewhere.</p></li> <li><p>If you ever work on WinForms components you deal with "services", like <code>INameCreationService</code> or <code>IExtenderProviderService</code>. You don't even really know what what the concrete classes <em>are</em>. .NET actually has its own IoC container, <code>IContainer</code>, which gets used for this, and the <code>Component</code> class has a <code>GetService</code> method which is the actual service locator. Of course, nothing prevents you from using any or all of these interfaces without the <code>IContainer</code> or that particular locator. The services themselves are only loosely-coupled with the container.</p></li> <li><p>Contracts in WCF are built entirely around interfaces. The actual concrete service class is usually referenced by name in a configuration file, which is essentially DI. Many people don't realize this but it is entirely possible to swap out this configuration system with another IoC container. Perhaps more interestingly, the service behaviors are all instances of <code>IServiceBehavior</code> which can be added later. Again, you could easily wire this into an IoC container and have it pick the relevant behaviors, but the feature is completely usable without one.</p></li> </ul> <p>And so on and so forth. You'll find DI all over the place in .NET, it's just that normally it's done so seamlessly that you don't even think of it as DI.</p> <p>If you want to design your DI-enabled library for maximum usability then the best suggestion is probably to supply your own default IoC implementation using a lightweight container. <code>IContainer</code> is a great choice for this because it's a part of the .NET Framework itself.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload