C# 如何使用Ninject
我今天一直在尝试使用Ninject,有几个问题。首先,我需要在我想要使用注入的所有构造函数上使用注入属性。这看起来真是个蹩脚的设计?我是否需要创建一个内核,然后在注入类中的任何地方使用它 首先,我需要在所有构造函数上使用Inject属性吗 我想注射用的。这看起来真是个蹩脚的主意 设计 不,实际上你根本不应该这么做。由于您使用ASP.NET MVC,因此只需安装Ninject.MVC3 Nuget包即可。这将使您从App_Start文件夹中的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
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
- 现在我可以将
传递给NoteCreatorWordDocumentCreator
- 现在我可以将该
传递到NoteCreator
main窗口
IDocumentCreator
(例如)无法解析
第二,如果管理层后来要求用户使用高级文字处理器,那么您所要做的就是
- 编写一个实现
的IDocumentCreator
WordPerfectDocumentCreator
- 将上面的
更改为将MyAppModule
绑定为IDocumentCreator
WordPerfectDocumentCreator
NoteCreator
,我不需要通过一个真实的WordDocumentCreator
(或者我正在使用的任何东西)。我可以通过一个假的。这样我就可以编写一个假设我的文档的测试