简体   繁体   中英

How to create a class without constructor parameter which has dependency injection

I have added the dependency injections to the project. But when i create an instance by using new keyword, dependency injection doesn't work.

public class MyClass
{
    ILoginTokenKeyApi _loginTokenKeyApi;

    public MyClass(ILoginTokenKeyApi loginTokenKeyApi)
    {
        _loginTokenKeyApi = loginTokenKeyApi;
    }

    ...
}

When i try to create an instance of MyClass, it wants a parameter to be constructed naturally.

Just like this :

MyClass mc = new MyClass(); // ERROR, it wants a parameter (but it is what i want)

I have to do :

MyClass mc = new MyClass(new LoginTokenKeyClass()); // this is not a good code for me

How i create an instance of MyClass without parameter because it has dependency injected.

But when i create an instance by using new keyword, dependency injection doesn't work.

That's fundamentally how dependency injection works.

With dependency injection, you are simply not supposed to new up new objects. That's the whole point of dependency injection and inversion of control . Instead of creating objects and managing those objects' dependencies, you are depending on the framework to give you the dependencies you need without having you to care about where they actually come from and how they are constructed properly. So you are moving the responsibility to create the object up to the caller.

If you find yourself in need to create an object that has a dependency, then this is a clear sign that you are doing it wrong. A common reason for this is that you want to create the object in order to manage its lifetime, or because it is actually a data object that just happens to have some operations that needs other dependencies to work (eg an entity that has a “save” method). In the first case, you simply don't do it like that. You just depend on it and let the framework manage the lifetime; if it has an incorrect lifetime, then you should reconfigure it with the DI container.

In the latter case where you have a data object with operations, you should split this up. You should just have a data object, without any logic, and then inject some manager service that is able to perform the operation on that data object for you.

For example in ASP.NET Core Identity, you have the User object which is just a normal entity without any logic. In order to eg add user roles or change the password, you rely on the user manager which you can inject. So the User object itself is without any dependencies.

I'd generally suggest you to read the dependency injection chapter of the ASP.NET Core documentation to understand how dependency injection works and how it is supposed to be used within the framework.

As mentioned in the comments, it is not clear what you trying to achieve, but in order to do DI in .Net Core you have to create an interface IMyClass, then let your class implement that interface,

public interface IMyClass {
   void SampleMethod();
}

public class MyClass : IMyClass
{
    ILoginTokenKeyApi _loginTokenKeyApi;

    public MyClass(ILoginTokenKeyApi loginTokenKeyApi)
    {
        _loginTokenKeyApi = loginTokenKeyApi;
    }

    public void SampleMethod()
    {
        // method logic goes here...
        var xx = _loginTokenKeyApi.WhatEver;
    }
}

then register ILoginTokenProvider and IMyClass in startup.cs

services.AddTransient<ILoginTokenProvider, LoginTokenProvider>();
services.AddTransient<IMyClass, MyClass>();

finally inject IMyClass where you need it:

public class IndexModel : PageModel {

    private readonly IMyClass _myClass;

    public IndexModel(IMyClass myClass)
    {
        _myClass = myClass;
    }

    public void OnGet()
    {
       _myClass.SampleMethod();
    }
}

btw, it is also possible to register and inject MyClass without implementing IMyClass interface, but I prefer to follow basic programming principals :)

There are two types of Dependency Injections.

  1. Constructor Injection - which you dont want
  2. Property Injection - In this - you expose Public Get/Set property of the Object you want to be injected. And then in your DI config file (like spring.net) you can assign values.

Another way you can do DepInjection is that in the param less constructor - you can get the Object by a Key/Name. Like in Spring.Net we would do:

var UtilityObject = Spring.ContextRegistry.GetContext().GetObject("MyUtilObject") as TheUtilityClass;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM