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
.
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.
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.
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.
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(); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With