Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Ninject_C#_Asp.net Mvc_Dependency Injection_Ninject - Fatal编程技术网

C# 如何使用Ninject

C# 如何使用Ninject,c#,asp.net-mvc,dependency-injection,ninject,C#,Asp.net Mvc,Dependency Injection,Ninject,我今天一直在尝试使用Ninject,有几个问题。首先,我需要在我想要使用注入的所有构造函数上使用注入属性。这看起来真是个蹩脚的设计?我是否需要创建一个内核,然后在注入类中的任何地方使用它 首先,我需要在所有构造函数上使用Inject属性吗 我想注射用的。这看起来真是个蹩脚的主意 设计 不,实际上你根本不应该这么做。由于您使用ASP.NET MVC,因此只需安装Ninject.MVC3 Nuget包即可。这将使您从App_Start文件夹中的NinjectMVC3类开始。您可以使用Register

我今天一直在尝试使用Ninject,有几个问题。首先,我需要在我想要使用注入的所有构造函数上使用注入属性。这看起来真是个蹩脚的设计?我是否需要创建一个内核,然后在注入类中的任何地方使用它

首先,我需要在所有构造函数上使用Inject属性吗 我想注射用的。这看起来真是个蹩脚的主意 设计

不,实际上你根本不应该这么做。由于您使用ASP.NET MVC,因此只需安装Ninject.MVC3 Nuget包即可。这将使您从App_Start文件夹中的
NinjectMVC3
类开始。您可以使用
RegisterServices
方法向Ninject注册接口/类。所有依赖于这些接口的控制器都将由Ninject自动解析,而不需要Inject属性

我是否需要创建一个内核,然后在一个 注射类

否-您所描述的听起来更像是依赖项注入,而不是依赖项注入-您将希望在构造函数中传递您的依赖项,而不是在使用内核的特定类中解析它们。应该只有一个完成解析的中心合成根,它位于上面提到的
RegisterServices
方法中的合成根中,或者在那里实例化一个单独的Ninject模块-后一种方法将允许您有更多的灵活性和模块性(没有双关语)在更改解决依赖关系的方式时


这里有一个好方法。

开始使用Ninject的最好方法是从小处着手。查找新的

在应用程序中间的某个地方,在另一个类中创建一个类。这意味着您正在创建一个依赖关系。依赖项注入是关于传入这些依赖项,通常是通过构造函数,而不是嵌入这些依赖项

假设您有这样一个类,用于在Word中自动创建特定类型的便笺。(这类似于我最近在工作中完成的一个项目。)

WordDocumentCreator
是一个类,用于处理在Microsoft Word中创建新文档的细节(创建Word实例等)。我的类,
NoteCreator
,依赖于
WordDocumentCreator
来执行其工作

问题是,如果有一天我们决定使用更高级的文字处理器,我必须找到所有实例化
WordDocumentCreator
的地方,并将它们改为实例化
WordPerfectDocumentCreator

现在想象一下,我将我的类更改为如下所示:

class NoteCreator
{
    WordDocumentCreator docCreator;

    public NoteCreator(WordDocumentCreator docCreator)  // constructor injection
    {
        this.docCreator = docCreator;
    }

    public NoteHost Create()
    {
        docCreator.CreateNewDocument();
        [etc.]
class MyAppModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDocumentCreator>()
            .To<WordDocumentCreator>();
我的代码变化不大;我在
Create
方法中所做的就是用
new
删除该行。但现在我注入了我的依赖性。让我们再做一个小小的改变:

class NoteCreator
{
    IDocumentCreator docCreator;

    public NoteCreator(IDocumentCreator docCreator)  // change to interface
    {
        this.docCreator = docCreator;
    }

    public NoteHost Create()
    {
        docCreator.CreateNewDocument();
        [etc.]
我用
CreateNewDocument
方法提取了一个
IDocumentCreator
接口,而不是传递一个具体的
WordDocumentCreator
。现在我可以传入实现该接口的任何类,而
NoteCreator
所要做的就是调用它知道的方法

现在是棘手的部分。我的应用程序现在应该有一个编译错误,因为我在某处创建了一个不再存在的无参数构造函数
NoteCreator
。现在我也需要摆脱这种依赖。换句话说,我经历了与上面相同的过程,但现在我将其应用于创建新
NoteCreator
的类。当您开始提取依赖项时,您会发现它们往往会“冒泡”到应用程序的根,这是您应该引用DI容器(例如Ninject)的唯一地方

我需要做的另一件事是配置Ninject。基本部分是一个类,看起来如下所示:

class NoteCreator
{
    WordDocumentCreator docCreator;

    public NoteCreator(WordDocumentCreator docCreator)  // constructor injection
    {
        this.docCreator = docCreator;
    }

    public NoteHost Create()
    {
        docCreator.CreateNewDocument();
        [etc.]
class MyAppModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDocumentCreator>()
            .To<WordDocumentCreator>();
类MyAppModule:NinjectModule
{
公共覆盖无效负载()
{
绑定()
.To();
这告诉Ninject,当我试图创建一个需要
IDocumentCreator
的类时,它应该创建一个
WordDocumentCreator
并使用它。Ninject所经历的过程如下所示:

class NoteCreator
{
    WordDocumentCreator docCreator;

    public NoteCreator(WordDocumentCreator docCreator)  // constructor injection
    {
        this.docCreator = docCreator;
    }

    public NoteHost Create()
    {
        docCreator.CreateNewDocument();
        [etc.]
class MyAppModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDocumentCreator>()
            .To<WordDocumentCreator>();
  • 创建应用程序的
    main窗口
    。其构造函数需要
    NoteCreator
  • 好的,创建一个NoteCreator。但是它的构造函数需要一个
    IDocumentCreator
  • 我的配置是,对于
    IDocumentCreator
    ,我应该使用
    WordDocumentCreator
    。因此,创建一个
    WordDocumentCreator
  • 现在我可以将
    WordDocumentCreator
    传递给NoteCreator
  • 现在我可以将该
    NoteCreator
    传递到
    main窗口
这个系统的优点有三个

首先,如果您未能配置某些内容,您将立即知道,因为您的对象是在应用程序运行后立即创建的。Ninject将向您提供一条有用的错误消息,说明您的
IDocumentCreator
(例如)无法解析

第二,如果管理层后来要求用户使用高级文字处理器,那么您所要做的就是

  • 编写一个实现
    IDocumentCreator
    WordPerfectDocumentCreator
  • 将上面的
    MyAppModule
    更改为将
    IDocumentCreator
    绑定为
    WordPerfectDocumentCreator
第三,如果我想测试我的
NoteCreator
,我不需要通过一个真实的
WordDocumentCreator
(或者我正在使用的任何东西)。我可以通过一个假的。这样我就可以编写一个假设我的
文档的测试