Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection with classes other than a Controller class

At this point I'm injecting things into my Controllers with ease, in some cases building my own ResolverServices class. Life is good.

What I cannot figure out how to do is get the framework to automatically inject into non-controller classes. What does work is having the framework automatically inject into my controller IOptions, which is effectively the configuration for my project:

public class MessageCenterController : Controller {     private readonly MyOptions _options;      public MessageCenterController(IOptions<MyOptions> options)     {         _options = options.Value;     } } 

I'm thinking whether I can do the same for for my own classes. I assume I'm close when I mimic the controller, like this:

public class MyHelper {     private readonly ProfileOptions _options;      public MyHelper(IOptions<ProfileOptions> options)     {         _options = options.Value;     }      public bool CheckIt()     {         return _options.SomeBoolValue;     } } 

I think where I'm failing is when I call it like this:

public void DoSomething() {     var helper = new MyHelper(??????);      if (helper.CheckIt())     {         // Do Something     } } 

The problem I have tracking this down is practically everything that talks about DI is talking about it at the controller level. I tried hunting down where it happens in the Controller object source code, but it gets kinda crazy in there.

I do know I can manually create an instance of IOptions and pass it to the MyHelper constructor, but it seems like I should be able to get the framework do that since it works for Controllers.

like image 873
Robert Paulsen Avatar asked May 12 '16 14:05

Robert Paulsen


People also ask

Is dependency injection possible with abstract class?

A: We can use whatever abstractions we like with Dependency Injection. The type of abstraction is completely separate from dependency injection itself. That means we can use interfaces, abstract classes, or base classes.

Can you dependency inject a static class?

You can use dependency injection in a static class using method or property injection. However, you cannot use constructor injection in a static class because the constructor of a static class cannot accept any parameters.

How do you inject a class in C#?

Using dependency injection, we modify the constructor of Runner to accept an interface ILogger, instead of a concrete object. We change the Logger class to implement ILogger. This allows us to pass an instance of the Logger class to the Runner's constructor.


1 Answers

Below is a working example of using DI without anything that involves MVC Controllers. This is what I needed to do to understand the process, so maybe it will help somebody else.

The ShoppingCart object gets, via DI, an instance of INotifier (which notifies the customer of their order.)

using Microsoft.Extensions.DependencyInjection; using System;  namespace DiSample {     // STEP 1: Define an interface.     /// <summary>     /// Defines how a user is notified.      /// </summary>     public interface INotifier     {         void Send(string from, string to, string subject, string body);     }      // STEP 2: Implement the interface     /// <summary>     /// Implementation of INotifier that notifies users by email.     /// </summary>     public class EmailNotifier : INotifier     {         public void Send(string from, string to, string subject, string body)         {             // TODO: Connect to something that will send an email.         }     }      // STEP 3: Create a class that requires an implementation of the interface.     public class ShoppingCart     {         INotifier _notifier;          public ShoppingCart(INotifier notifier)         {             _notifier = notifier;         }          public void PlaceOrder(string customerEmail, string orderInfo)         {             _notifier.Send("[email protected]", customerEmail, $"Order Placed", $"Thank you for your order of {orderInfo}");         }      }      public class Program     {         // STEP 4: Create console app to setup DI         static void Main(string[] args)         {             // create service collection             var serviceCollection = new ServiceCollection();              // ConfigureServices(serviceCollection)             serviceCollection.AddTransient<INotifier, EmailNotifier>();              // create service provider             var serviceProvider = serviceCollection.BuildServiceProvider();              // This is where DI magic happens:             var myCart = ActivatorUtilities.CreateInstance<ShoppingCart>(serviceProvider);              myCart.PlaceOrder("[email protected]", "2 Widgets");              System.Console.Write("Press any key to end.");             System.Console.ReadLine();         }     } } 
like image 110
Robert Paulsen Avatar answered Oct 06 '22 12:10

Robert Paulsen