【问题标题】:Basic dependency injection issue基本的依赖注入问题
【发布时间】:2014-12-16 22:39:50
【问题描述】:

我正在尝试在我的 Job 类中依赖注入我的存储库(使用 Ninject):

public class Job
{
    IRepository _repo;
    public Job(IRepository repo)
    {
        _repo = repo;
    }

    public void Save()
    {
        repo.SaveJob(this);
    }
}

我现在的问题是我需要从另一个类实例化 Job 类。 在依赖注入存储库时如何创建它? 我的意思是构造函数需要一个存储库。

【问题讨论】:

  • 通常存储库中的对象不依赖存储库。如果您现在确实想创建一个作业,则需要使用 Ninject 创建一个。
  • @Jacob 我明白了。但重点不在于作业是否在存储库中。我需要“使用 Ninject 来创建一个”——你到底是什么意思?
  • 你可以有一个依赖于 Job 的类并让 Ninject 为你创建它。否则,您将需要对 Ninject 容器的引用并从那里创建它。以 MVC 为例,您的控制器可能依赖于存储库,模型(作业)将不依赖于任何东西。控制器可以创建一个作业并使用存储库来保存它。
  • 使用 Unity 会是 job = container.Resolve<Job>();,不知道如何使用 ninject... 另外取决于使用类的代码,DI 容器提供的一些创建器函数可能更有用.
  • @AlexeiLevenkov 方法:System.Web.Mvc.DependencyResolver.Current.GetService(typeof (IRepository));获取存储库。非常感谢您的帮助。

标签: c# asp.net-web-api dependency-injection ninject


【解决方案1】:

您需要使用 ninject 或替代方法来解决依赖关系。在 ninject 中将 IRepo 绑定到 Repo,并且 ninject 会将具体实现传递给构造函数,而无需显式注入您自己的 Repo 实现,如上一个答案所示。

【讨论】:

  • 依赖注入本身不是我的问题。我只是不明白如何在依赖注入存储库的同时实例化我的 Job 类。
  • 您的其他类也需要使用依赖注入来创建作业类的实例。请为作业类创建一个接口,以便 Ninject 在您调用作业类时负责在作业类构造函数中注入一个 repo
  • 无论我是否为 Job 创建接口,我都需要将 IRepository 的实例传递给 Job,不是吗?
  • 容器的工作是根据你的注册解析依赖树。
  • 所以换句话说,你不需要将 irepo 的实例传递给作业,因为 ninject 会处理这个
【解决方案2】:

说明你是否在以下课程中实现了IRepository

public class MyFirstRepo : IRepository
{
   // Implement IRepository
}

public class MySecondRepo : IRepository
{
   // Implement IRepository
}

那么这就是你实例化的方式

MyFirstRepo firstRepo = new MyFirstRepo();
Job myJob1 = new Job(firstRepo);

MySecondRepo secondRepo = new MySecondRepo();
Job myJob2 = new Job(secondRepo);

更新

如何使用 Ninject 实例化

您确实需要在项目中添加对 Ninject.dll 程序集的引用,并在项目中创建一个单独的类,Ninject 使用该类在运行时配置依赖项:

using Ninject.Modules;
using Ninject; 
public class Bindings : NinjectModule
{
    public override void Load()
    {
        Bind<IRepository>().To<MyFirstRepo>();
    }
}

您的调用代码 (Program.cs) 必须使用 Ninject 来确定要使用的具体实现:

using Ninject;
class Program
{
    static void Main(string[] args)
    {
        IKernel kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());
        IRepository firstRepo = kernel.Get<IRepository>();

        Job myJob1 = new Job(firstRepo);
        // Now myJob1 is instantiated

        Console.ReadLine();
    }
}

【讨论】:

  • @AlexeiLevenkov 我明白了。但是在我的示例中,我将如何实例化作业?
  • @AlexeiLevenkov 这是构造函数注入。如果我错了,请告诉我们你会怎么做。我在这里没有使用 Unity 或 Ninject。
  • 是的,我刚刚注意到了。我的错。但我不同意你的评论,说我的回答不是 DI 的一部分。
  • 提供的示例显示了依赖注入的最基本方法。对于大多数用途来说,这并不实用(因为现有的依赖容器会像 ninject、Unity、CastleWindor 等一样使用)。示例也没有解决如何使用 ninject 创建Job 对象并正确解决依赖关系的实际问题。
猜你喜欢
  • 2015-11-21
  • 2016-05-18
  • 2014-12-27
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
相关资源
最近更新 更多