4

I have a simple class which looks like this:

public class TestClass1
{
    private string testString = "Should be set by DI";

    public TestClass1(string testString)
    {
        this.testString = testString;
    }
    public string GetData()
    {
        return testString + DateTime.Now;
    }
}

I want to inject it using the build-in DI in a simple ASP.NET core web app, but with the "testString" parameter set when initialising the Dependency Injection.

I've tried setting the following in startup.cs but it fails at runtime because TestClass1 doesn't have a parameterless constructor:

services.AddScoped(provider => new TestClass1("Success!")); 
9
  • 2
    Your question doesn't make sense; the code you posted will work just fine. You are probably missing some crucial information in your question, but I can't determine what you are missing. Please post the exception details you get (exception type, message, stacktrace and inner exception details). Commented Jul 13, 2016 at 14:34
  • Are you really injecting this class do you try to initialize it with ´new` like in new TestClass()? DI doesn't work like this Commented Jul 13, 2016 at 14:37
  • Could you post your ConfigureServices method? Commented Jul 13, 2016 at 14:41
  • 1
    @Tseng: sure, sometime you need to register an instance of an type directly. So this is a common scenario. As already written by Steven, it should work like this. Commented Jul 13, 2016 at 14:49
  • @JuergenGutsch: No, you don't use new keyword when obtaining an instance. You always inject it via constructor. DI is not some compiler magic, it's just plain CLR/OOP with a bit of reflection or ExpressionTrees. I suspect he does new TestClass() in his code (notice the new keyword and no parameter). That's not how DI works. Rather you pass it via constructor like public MyService(TestClass injectedTestCass) Commented Jul 13, 2016 at 14:52

1 Answer 1

1

I suspect you just missed the cruical part of the code and your usage of the DI is just plain wrong, not the registration.

public class MyController 
{
    private readonly MyClass myClass;

    public MyController()
    {
        // This doesn't work and do not involve DI at all
        // It will fail because MyClass has no parameterles constructor
        this.myClass = new MyClass(); 
    }
}

The above won't work, because DI is no compiler magic that let you magically inject dependencies when calling new on the type.

public class MyController 
{
    private readonly MyClass myClass;

    public MyController(MyClass myClass)
    {
        // This should work, because the IoC/DI Container creates the instance
        // and pass it into the controller
        this.myClass = myClass;
    }
}

When you use DI/IoC you let the constructor generate and instantiate the objects, hence you never call new in your service classes. Just tell in the constructor that you need an instance of some type or it's interface.

Edit:

This used to work in previous versions (betas) of ASP.NET Core. Should still work, but limited to parameters:

public class MyController 
{
    public IActionResult Index([FromServices]MyClass myClass)
    {
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you soooooo much. I tried your piece of code and of course it worked. Then I checked my own code and my mistake was to put the TestClass testClass in the ActionResult method instead of in the Controller constructor method. And also thanks to @steven for pointing my in right direction :)
You should have added your use case and the example code in question in the answer, then it would have been way faster than guessing what the error may be. For Actions there used to be a method to inject too, using [FromServices] attribute on the parameter. docs.asp.net/en/latest/mvc/controllers/… That has been changed a few times (i.e. to be removed from properties and controller) as pointed out on this GitHub issue github.com/aspnet/Mvc/issues/3578. I dunno if it still works on Action parameters though

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.