Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.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
Dependency injection 使用基于约定的注册时,如何表示组件寿命?_Dependency Injection_Inversion Of Control_Ioc Container - Fatal编程技术网

Dependency injection 使用基于约定的注册时,如何表示组件寿命?

Dependency injection 使用基于约定的注册时,如何表示组件寿命?,dependency-injection,inversion-of-control,ioc-container,Dependency Injection,Inversion Of Control,Ioc Container,我读了很多关于国际奥委会容器的文章,特别是马克·希曼的博客文章,他在其中强调了国际奥委会容器的重要性。我理解并同意他的观点,但我想知道如何最好地为一个不规则的一生划出一门课 例如,我的大多数服务都是用瞬时生存期注册的,但我希望某个特定的服务注册为单例,因为它可以进行一些有用的缓存 我曾考虑过使用一些自定义属性,但我读过反对这一点的论据(因为它将合成逻辑放在类中) 例如,我对配置原语的依赖性进行了同样的讨论。最终我使用了parameter属性,因为它在我的例子中起作用,但我觉得可能我没有看到“隐藏

我读了很多关于国际奥委会容器的文章,特别是马克·希曼的博客文章,他在其中强调了国际奥委会容器的重要性。我理解并同意他的观点,但我想知道如何最好地为一个不规则的一生划出一门课

例如,我的大多数服务都是用
瞬时
生存期注册的,但我希望某个特定的服务注册为
单例
,因为它可以进行一些有用的缓存

我曾考虑过使用一些自定义属性,但我读过反对这一点的论据(因为它将合成逻辑放在类中)


例如,我对配置原语的依赖性进行了同样的讨论。最终我使用了parameter属性,因为它在我的例子中起作用,但我觉得可能我没有看到“隐藏的危险”。

IoC容器允许您指定对象的生活方式是很常见的。例如,SimpleInjector提供了瞬态和单例开箱即用(还允许用户创建自定义的生活方式类)。使用SimpleInjector,它非常简单:

container.Register(lifesture.Singleton);

container.Register(lifesture.Transient);
没有必要用合成逻辑来污染你的类

对于配置原语,通常的做法是将它们放在接口后面。例如,我将连接字符串放在IDatabaseConfiguration接口后面,它的实现从web.config读取值。然后,我将该接口注入到我的数据服务中

编辑:忽略上面的内容。把它保存起来,这样评论才有意义

下面的内容实际上并没有回答这个问题,但它可能解决了引发这个问题的问题。你说这个类做了一些有用的缓存,这让我意识到它承担了额外的责任。因此,我建议您不要尝试将单个实现注册为单例,而是围绕该实现创建一个decorator类

container.RegisterDecorator(
类型(ICommandHandler),
类型(CommandHandlerCacheDecorator),
生活方式,短暂,
x=>{return/*一些查找和的逻辑
找到所需的一个类
装饰*/
});
装饰器需要是一个瞬态的,因为它将有一个对它装饰的命令的瞬态引用。但是,它可以访问单独的单例类(当然是通过依赖项注入)或处理实际缓存的缓存对象

编辑:选择要装饰的一个类的示例。根据你想要的具体程度,有很多选择。同样,SimpleInjector也是如此,但我相信其他容器也有自己的类似物

//装饰一个特定的类
x=>{return x.ImplementationType.FullName==“My.Commands.Web.SomeName”;}
//修饰所有共享某个命名空间的类
x=>{return x.ImplementationType.Namespace.EndsWith(“Commands.Web”);}
//修饰实现相同接口的所有类
x=>{return x.ImplementationType.IsInstanceOfType(typeof(ICouldCache));}

我认为这并不能回答问题,因为您的代码不是约定优于配置(CoC)的示例。CoC的一个例子是:
container.RegisterManyForOpenGeneric(typeof(IValidator),assembly)
。在这里,所有验证器都在一行中注册,使用它们实现特定接口的约定。这个例子直接说明了问题所在,因为现在所有类型都注册为transient。但是如果其中一个验证器必须注册为singleton呢?这就是问题所在。感谢Steven澄清这一点,感谢Facio提供的见解,我认为你完全正确,最终这是一个可能是暂时的类的单体装饰器。然而,我仍然不确定如何在不明确的情况下将这个类标记为装饰类——也许没有合适的答案!目前,我将保持开放状态,希望有。我添加了几个示例。最后,如果你能用人类语言解释你想要什么,你就应该能够为它制定一个惯例。