Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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
Design patterns 在类库中创建Ninject内核_Design Patterns_Ioc Container_Ninject - Fatal编程技术网

Design patterns 在类库中创建Ninject内核

Design patterns 在类库中创建Ninject内核,design-patterns,ioc-container,ninject,Design Patterns,Ioc Container,Ninject,我有一个类,它具有与Ninject关联的依赖项 public interface IFoo {} public class MyObject { [Inject] IFoo myfoo; } 在实际的实现中,我使用属性注入,但为了快速说明,我将在字段上进行注入。据我所知,为了正确注入依赖项,我需要使用 kernel.Get<MyObject>() kernel.Get() 然而,我遇到的问题是MyObject只能在类库的上下文中使用。其目的是让终端应用程序创建

我有一个类,它具有与Ninject关联的依赖项

public interface IFoo {}

public class MyObject {
    [Inject]
    IFoo myfoo;
}
在实际的实现中,我使用属性注入,但为了快速说明,我将在字段上进行注入。据我所知,为了正确注入依赖项,我需要使用

kernel.Get<MyObject>()
kernel.Get()
然而,我遇到的问题是MyObject只能在类库的上下文中使用。其目的是让终端应用程序创建自己的模块,并将其传递到内核实例中以供使用。考虑到这一点,在我的类库中呈现Ninject内核的泛型实例以使MyObject的实例(以及其他类似的情况)可以被水合时,通常最实用的方法是什么

我的第一个倾向是某种内部化单例内核的工厂——应用程序本身必须通过加载一个模块来实现/初始化单例内核

所以在RandomService.cs中

var myKernel = NinjaFactory.Unleash();
var myobj = myKernel.Get<MyObject>();
myobj.foo();
var myKernel=NinjaFactory.release();
var myobj=myKernel.Get();
myobj.foo();

在我走得太远之前,我需要做一个理智的检查,以确保我的想法是正确的,或者没有其他明显的遗漏。显然,我是国际奥委会的新手,感觉自己在摸索基础知识,但不一定是最佳的实际使用方法。

我不确定我是否理解你问题中的所有细节,但据我所知,你在问如何将对Ninject的依赖具体化

可以写(Ninject或其他任何东西)。这使得库的使用者可以选择他或她喜欢的DI容器(或者根本不使用容器)。这种方法更受欢迎,因为它提供了更大的自由度

但是,您应该真正喜欢构造函数注入而不是属性注入。虽然属性注入看似简单,但实际上很难正确实现


构造函数注入的最大优点之一是,您不需要在构造函数上添加任何属性,因为它在结构上已经包含了DI容器正确连接所需的所有信息。

Mark的观点肯定是我的出发点(因此是+1)NB别忘了关注他的链接

就我个人而言,我在过去很快就放弃了属性(或字段)的构造函数(我的“借口”)作为一个基类需要5个属性,我不想让所有的派生类都有这个负担。解决这个问题的方法是将涉及的5个属性封装在一个类或类的层次结构中,表示属性所代表的任何底层概念。有点像引入参数对象重构

关于我发现有用的注意事项的一个很好的讨论是(找不到提到它的SO帖子和它周围的一些主题,也许有人会插入一个链接:D)

另一个总结了其中一些观点的博客是


以下是在当前程序集中查找所有ninject模块的通用方法:

IKernel _serviceKernel = new StandardKernel();

Assembly myAssembly = this.GetType().Assembly;

IEnumerable<Type> ninjectModuleTypes = 
     myAssembly.GetTypes().Where(type => type.BaseType == typeof(NinjectModule));

foreach (Type ninjectModuleType in ninjectModuleTypes)
{
    NinjectModule mod = (NinjectModule)Activator.CreateInstance(ninjectModuleType);
    _serviceKernel.Load(mod);
}
IKernel\u serviceKernel=new-StandardKernel();
Assembly myAssembly=this.GetType().Assembly;
IEnumerable NinjectModuleType=
myAssembly.GetTypes().Where(type=>type.BaseType==typeof(NinjectModule));
foreach(在ninjectModuleType中键入ninjectModuleType)
{
NinjectModule mod=(NinjectModule)Activator.CreateInstance(ninjectModuleType);
_加载(mod);
}

幸运的是,这是一个内部问题(在公司意义上)lib所以我有一个固定的受众——我团队中的其他开发人员,使用一个标准工具。现在,每个开发人员可能有他们想要的不同绑定,因此我有了最初的quandry。关于:ctor vs prop injection,prop显然有很多我不得不写的东西,但我担心依赖列表会随着时间的推移而增长,从而导致ctor调用。是吗这里是我应该注意的支持注入的其他缺点?即使使用内部应用程序,我仍然会遵循相同的原则,因为它们会导致更干净的代码和更好的关注点分离。属性注入存在许多潜在问题,包括保护不变量(依赖项是否为空?)可能是注入的依赖性的热交换(可能不是你想做的事情)和一个更模糊的API。一般来说,只需在前面做一个明确的说明:我认为服务定位器是一种反模式:是的,但是不要忘记,公共服务定位器能够同时做DI和SL. Don,而不会被名称分心;-好的,在阅读了马克的各种链接以及这些链接中的一些链接后,我觉得自己对所提倡的观点感到非常舒服。这就是答案。