如何创建不具有依赖项注入的构造函数参数的类

时间:2018-09-26 02:45:45

标签: c# asp.net asp.net-core dependency-injection parameter-passing

我已将依赖项注入添加到项目中。但是,当我使用 new 关键字创建实例时,依赖项注入无效。

public class MyClass
{
    ILoginTokenKeyApi _loginTokenKeyApi;

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

    ...
}

当我尝试创建MyClass的实例时,它希望自然构造一个参数。

就是这样:

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

我必须做:

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

我如何创建不带参数的MyClass实例,因为它已注入依赖项。

3 个答案:

答案 0 :(得分:4)

  

但是当我使用new关键字创建实例时,依赖项注入不起作用。

从根本上讲,这就是依赖注入的工作原理。

使用依赖项注入,根本不应该new创建新对象。这就是dependency injectioninversion of control的重点。无需创建对象和管理对象的依赖关系,而是依靠框架赋予您需要的依赖关系,而无需关心它们的实际来源和来源。 它们的正确构造方式。因此,您将创建对象的责任移交给了调用者。

如果发现自己需要创建一个具有依赖关系的对象,那么这很明显表明您做错了。造成这种情况的常见原因是,您想创建对象以管理其生命周期,或者因为它实际上是一个数据对象,而恰好恰好具有某些需要其他依赖项才能起作用的操作(例如,具有“保存”功能的实体“ 方法)。在第一种情况下,您根本不会那样做。您只需要依靠它,就可以让框架管理生命周期。如果生存期不正确,则应使用DI容器对其进行重新配置。

在后一种情况下,如果您的数据对象带有操作,则应将其拆分。您应该只具有一个数据对象,没有任何逻辑,然后注入一些管理器服务,该服务能够为您对该数据对象执行操作。

例如,在ASP.NET Core Identity中,您拥有User对象,它只是一个普通实体,没有任何逻辑。为了例如添加用户角色或更改密码,则取决于您可以注入的用户管理器。因此User对象本身没有任何依赖性。

我通常建议您阅读ASP.NET Core文档的dependency injection chapter,以了解依赖项注入的工作原理以及应该在框架中使用它的方式。

答案 1 :(得分:0)

如评论中所述,不清楚要实现的目标,但是为了在.Net Core中进行DI,必须创建一个接口IMyClass,然后让您的类实现该接口,

no instance of type variable T,U exists so that String conforms to Function<? super T, ? extends U>

然后在startup.cs中注册ILoginTokenProvider和IMyClass

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;
    }
}

最终在需要的地方注入IMyClass:

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

顺便说一句,也可以在不实现IMyClass接口的情况下注册和注入MyClass,但我更喜欢遵循基本的编程原则:)

答案 2 :(得分:-1)

有两种类型的依赖项注入。

  1. 构造函数注入-您不想要
  2. 属性注入-在此方法中,您将公开要注入的对象的“公共获取/设置”属性。然后在您的DI配置文件(如spring.net)中可以分配值。

可以执行DepInjection的另一种方法是在无参数构造函数中-通过键/名称获取对象。就像在Spring.Net中一样,我们会这样做:

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