2

I am trying to use the new ASP.NET 5 dependency injection system, but it seems limited to ONLY constructors of classes that inherit from Controller.

Is there any other way to inject things? Properties? Anything? This is so severely limiting and has had me brickwalling for days.

Ciel
  • 4,290
  • 8
  • 51
  • 110
  • that is not true at all, any class with a constructor can easily registered with DI and injected wherever they are needed so long as all the types needed by the constructor are also registered in DI. each dependency in the chain must be registered with DI. what makes you think it is limited to controllers? – Joe Audette Jan 05 '16 at 18:18
  • 1) I can't find any examples otherwise. 2) I don't understand how the class gets instantiated then. What creates it? – Ciel Jan 05 '16 at 18:23
  • I would be greatly in your debt if you could show me an example of how this works on other classes. I'm just not "getting" it. It is driving me up a wall of crazy. – Ciel Jan 05 '16 at 18:25
  • The major thing I can't figure out is how another class could get created. – Ciel Jan 05 '16 at 18:40
  • @Ciel: You should include the code example which demonstrates what you want to implement, especially **which relation have the code with the HTTP requests**, which come from clients of ASP.NET application. It's important that DI allows to extend `HttpContext` created on the new HTTP request. It contains `RequestServices` property (`HttpContext.RequestServices`) of the type `Microsoft.Extensions.DependencyInjection.ServiceProvider`. One can write controller action, exception handle, compression module etc which get custom information from `HttpContext.RequestServices`, but in a comfortable way. – Oleg Jan 05 '16 at 18:49
  • 1
    I think if you read [question and answer here](http://stackoverflow.com/questions/32599573/how-do-i-inject-asp-net-5-vnext-user-secrets-into-my-own-utility-class/32608820#32608820) as well as the discussion in comments it will help you – Joe Audette Jan 05 '16 at 18:54
  • I'm not entirely sure what the behavior I want is. I just know that I've got some dependencies that I really need to be in a service, non-controller class and I'm trying to figure out how to do it without just instantiating it with a dependency in a controller. I'm looking over this question you linked, and I'm not clear how they are related. – Ciel Jan 05 '16 at 18:57
  • I'm very lost. You still leave out the main thing I'm having trouble with in your other post; How to instantiate the object. I just don't get it, I'm sorry. What MAKES the object and injects it? – Ciel Jan 05 '16 at 19:21
  • In that example, yeah.. if you can get `MailMaker` to be created by something, great - dependencies. But that's where I'm so lost. What makes it? You can't just call `new MailMaker`, otherwise you would just do it. Is there some kind of activator or something? – Ciel Jan 05 '16 at 19:23
  • I'm sorry if I seem rushed. I'm just very frustrated with this whole thing. – Ciel Jan 05 '16 at 19:33
  • Is there no way to do it if the class being created doesn't exist anywhere near an `HttpContext`? – Ciel Jan 05 '16 at 19:49
  • @JoeAudette pasting my response below here, too. Alright... I'm looking back at this after having some time to sober up and WOW. I wasn't thinking straight at all. Thanks so much for putting up with me. I think the question I'm really asking is _"How do I get an instance of the service locator or activator to instantiate a class outside a web request? "_ – Ciel Jan 06 '16 at 18:26

2 Answers2

1

Just tested this (RC1 Update1), it works with other classes as well. I wrote a small example, first the type declarations:

public interface IBaseServiceType { }

public interface IComposedServiceType
{
    IBaseServiceType baseService { get; }
}

public class BaseServiceImplementation : IBaseServiceType { }

public class ComposedServiceImplementation : IComposedServiceType
{
    public IBaseServiceType baseService { private set; get; }

    public ComposedServiceImplementation(IBaseServiceType baseService)
    {
        this.baseService = baseService;
    }
}

The configuration:

        services.AddTransient(typeof(IBaseServiceType), typeof(BaseServiceImplementation));
        services.AddTransient(typeof(IComposedServiceType), typeof(ComposedServiceImplementation));

And create the instance like this where context is your HttpContext:

 var composedServiceInstance = context.ApplicationServices.GetService<IComposedServiceType>();
Michael Rätzel
  • 401
  • 1
  • 6
  • 17
  • Is it possible to get it even if you don't have an `HttpContext`? – Ciel Jan 05 '16 at 19:58
  • @Ciel: sure, you only need a reference to the `IServiceProvider` instance. – Michael Rätzel Jan 05 '16 at 20:06
  • Hrnm.. I'm trying to think of how to get that. Basically, I have a class that needs to run, but it isn't inside a Controller and it doesn't get an HttpContext at all. – Ciel Jan 05 '16 at 20:07
  • 1
    you will have to make a decision **_when_** your "*class needs to run*". – Michael Rätzel Jan 05 '16 at 20:09
  • @Ciel: basically you have two options to pass data: using the stack or static members. static members can be accessed without an instance. – Michael Rätzel Jan 05 '16 at 23:05
  • Alright... I'm looking back at this after having some time to sober up and WOW. I wasn't thinking straight at all. Thanks so much for putting up with me. I think the question I'm really asking is _"How do I get an instance of the service locator or activator to instantiate a class outside a web request? "_ – Ciel Jan 06 '16 at 18:24
  • That depends on from where your code would be called. As long as no code is run, you simply cannot. For example, the runtime serves you an instance of `IServiceProvider` via the `IApplicationBuilder` argument when it calls the `Configure` method on the instance of the Startup class. – Michael Rätzel Jan 06 '16 at 18:51
  • So it's `HttpContext` or Singleton, huh? That means it wouldn't even be possible to use this DI in a non-web app, would it? – Ciel Jan 07 '16 at 08:24
  • What prevents you from using this DI via the `IApplicationBuilder` instance from the `Configure` method in your *non-web app*? – Michael Rätzel Jan 07 '16 at 10:24
  • @Ciel: sorry, I misunderstood the question in your earlier comment. Just call your code from the `Configure` method in your startup class. There you can use DI via the `ApplicationServices` member of the `IApplicationBuilder` instance given by the runtime. Keep in mind though to configure your host accordingly to **not** wait for a request to start the application (as this is default for some popular hosts like IIS). In case you use IIS see http://stackoverflow.com/a/4333535/1698246 – Michael Rätzel Jan 07 '16 at 11:39
0

Register your class as a service and treat it like you would all other services

see Net Core Dependency Injection for Non-Controller

John Arundell
  • 118
  • 1
  • 6