Ninject依赖注入——两个具体的类

Ninject Dependency Injection - Two Concrete classes

我正在学习 Ninject 依赖注入,并且有一个用例,其中两个 classes 在 WPF MVVM 应用程序中实现相同的接口。在我的研究中,可以使用上下文绑定来绑定依赖项,但是我不确定在这种情况下它是如何工作的。

例如:

public interface IModifyContent {
    string ModifyOperation();
}

public class UpdateContent : IModifyContent {
    public string ModifyOperation() {
        return "This is the update operation";
    }
}

public class DeleteContent : IModifyContent {
    public string ModifyOperation() {
        return "This is the delete operation";
    }
}

public class ModifyFile {
    private IFileManager _fileManager;
    private IModifyContent _modifyContent;
    
    public ModifyFile(IFileManager fileManager, IModifyContent modifyContent) 
    {
        _fileManager = _fileManager;
        _modifyContent = modifyContent;
    }
    
    public void Modify() 
    {
        var fileContent = _fileManager.ReadFileContents(); // Returns file content
        
        var result = _modifyContent.ModifyOperation(); // ModifyOperation would actually modify content in some way...
        
        // Do stuff with result
    }
}

那么绑定看起来像这样:

Bind<IModifyContent>().To<UpdateContent>();
Bind<IModifyContent>().To<DeleteContent>();
// Other bindings

在此我的思考如下:

首先,这是避免重复通用逻辑的良好设计方法,其次,我如何根据 class/ 调用 ModifyFile 的内容注入正确的具体实现?

我认为如果你的两个具体 classes 来自不同的业务流程, 您可以将它们注册为具体 classes 而不是抽象。

我的意思是你可以注册

Bind<UpdateContent>().To<UpdateContent>();
Bind<DeleteContent>().To<DeleteContent>();

并且在您的 BusinessLogic class 中,您可以要求提供具体的 classes。

TLDR:两个 classes 具有接口的事实并不意味着您必须 从那里抽象使用它们。

有一种方法可以实现这一目标!!!

您可以使用特定名称注册依赖项。

IKernel ninjectKernel = new StandardKernel();

// Defining Bindings with specific names
ninjectKernel.Bind<IModifyContent>().To<UpdateContent>().Named("Update");
ninjectKernel.Bind<IModifyContent>().To<DeleteContent>().Named("Delete");

您可以在编译时解决这些依赖关系,如下所示:

// Resolving dependencies using binding name
IModifyContent updateContent = ninjectKernel.Get<IModifyContent>("Update");
IModifyContent deleteContent = ninjectKernel.Get<IModifyContent>("Delete");

一旦解决,他们就可以用来执行他们的代码。以下是参考您提供的实现的示例代码。

Console.WriteLine(updateContent.ModifyOperation());
Console.WriteLine(deleteContent.ModifyOperation());

// Output
// This is the update operation
// This is the delete operation

您也可以在 运行 时解决此类依赖关系。 有关详细信息,请参阅以下 link:

https://github.com/ninject/Ninject/wiki/Contextual-Binding