- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我希望能够根据控制反转原则创建一个服务,因此我创建了一个接口(interface)和一个服务类。
public interface IMyService
{
void DoSomeThing1();
void DoSomeThing2();
void DoSomeThing3();
string GetSomething();
}
public class MyService : IMyService
{
int _initialValue;
//...
public MyService(int initialValue)
{
_initialValue = initialValue;
}
public void DoSomeThing1()
{
//Do something with _initialValue
//...
}
public void DoSomeThing2()
{
//Do something with _initialValue
//...
}
public void DoSomeThing3()
{
//Do something with _initialValue
//...
}
public string GetSomething()
{
//Get something with _initialValue
//...
}
}
例如使用 Unity,我可以设置我的 IoC。
public static class MyServiceIoc
{
public static readonly IUnityContainer Container;
static ServiceIoc()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService, MyService>();
Container = container;
}
}
问题是构造函数参数。我可以使用像
这样的 ParameterOverridevar service = MyServiceIoc.Container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
但我不想使用松散类型的参数。如果有人更改构造函数参数名称或添加一个参数怎么办?他不会在完成时收到警告,也许除了最终用户之外没有人会检测到它。也许程序员为测试更改了 IoC 设置,但忘记了“发布”用法,那么即使是具有 100% 代码覆盖率的代码库也无法检测到运行时错误。
可以向接口(interface)和服务添加一个 Init 函数,但是服务的用户必须理解这一点,并记住在每次获得服务实例时调用 init 函数。该服务变得不那么 self 解释,并且对不正确的使用开放。如果方法不依赖于它们被调用的顺序,那是最好的。
使它更安全的一种方法是在 Ioc 上有一个创建函数。
public static class MyServiceIoc
{
//...
public IMyService CreateService(int initialValue)
{
var service = Container.Resolve<IMyService>();
service.Init(initialValue);
}
}
但如果您只看服务及其接口(interface),上述问题仍然存在。
有没有人对这个问题有可靠的解决方案?如何仍使用 IoC 以安全的方式将初始值传递给我的服务?
最佳答案
DI 容器是基于反射的,并且基本上是弱类型的。问题比 Primitive Dependencies 广泛得多- 它无处不在。
一旦你做了类似下面的事情,你就已经失去了编译时的安全性:
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService, MyService>();
var service = container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
问题是您可以删除第二个语句,代码仍然可以编译,但现在它不再有效了:
IUnityContainer container = new UnityContainer();
var service = container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
请注意,缺乏编译时安全性与具体依赖关系无关,但与涉及 DI 容器的事实有关。
这也不是 Unity 的问题;它适用于所有 DI 容器。
There are cases where a DI Container may make sense ,但在大多数情况下,Pure DI是一种更简单、更安全的替代方法:
IMyService service = new MyService(42);
在这里,如果其他人在您看向别处时更改了 API,您将收到编译器错误。很好:compiler errors give you more immediate feedback than run-time errors .
顺便说一句,当您传入原始依赖项并无形中将其变成 Concrete Dependency 时,你让客户更难理解发生了什么。
我建议改为这样设计:
public class MyService : IMyService
{
AnotherClass _anotherObject;
// ...
public MyService(AnotherClass anotherObject)
{
_anotherObject = anotherObject;
}
// ...
}
使用 Pure DI 组合仍然很容易且类型安全:
IMyService service = new MyService(new AnotherClass(42));
关于c# - IoC、依赖注入(inject)和构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32992976/
我开始认真考虑使用 IoC 容器会引发创建过度设计的解决方案(至少它会促使我尝试使用各种不必要的功能:)。 是时候将我的“IoC”反模式列表与社区列表同步了。 我短暂的经验告诉我们,在启动时每个应用程
我一直在阅读有关控制反转框架的内容,而我只是在玩弄这个问题:“我到底为什么需要一个框架来做到这一点?” 不要误解我的问题...该模式是我们程序员经常使用的,但是...一个功能齐全的框架可以做到这一点?
想要改进这篇文章?提供这个问题的详细答案,包括引文和解释为什么你的答案是正确的。没有足够细节的答案可能会被编辑或删除。 我正在尝试确定是否需要付出额外的努力来封装我的 IoC 容器。经验告诉我,我应该
有人建议我,在使用 IOC 容器时,我应该改变这个: class Foobar: IFoobar, IDisposable {}; 进入这个: interface IFoobar: IDisposab
《畜牧代码》播客第 68 期有人,http://herdingcode.com/herding-code-68-new-year-shenanigans/ ,表示 IOC 容器不适合使用 Python
我们正在使用 NInject 框架在我们的应用程序中实现 IoC/DI。我们有具有内部方法的内部类。要实现 IoC/DI,我们必须提取接口(interface)。但是如果我们在一个内部类中只有内部方法
Spring IOC 相关接口分析 1.BeanFactory Spring 中 Bean 的创建是典型的工厂模式,这一系列的 Bean 工厂,即 IOC 容器,为开发者管理对象之间的依赖关系提供了很
MEF is not an IoC container .不过好像是差不多 一个 IoC 容器。似乎我可以很容易地让 MEF 表现得像一个 IoC 容器(见下面的例子),而且让 MEF 成为一个完整的
只是想继续了解 IOC 的原则。 Q1:静态方法 - 具有静态辅助方法的实用程序类是否应该与 IOC 连接? 例如,如果我有一个带有许多静态方法的 HttpUtils 类,我是否应该尝试通过 IOC
众所周知,在asp.net Startup 类中有一个方法ConfigureServices,我们可以添加自定义服务。服务通过依赖注入(inject)提供。 ASP.NET Core includes
所以..我一直在深入研究 IoC 容器和服务定位器。 我认为 IoC 容器是 IoC 容器,而不是服务定位器,因为 您使用它的方式。您将服务定位器传递给需要依赖项的类,然后通过容器检索依赖项。另一方面
阅读许多有关这三个成语之间差异的帖子。但是比较困惑,然后我遇到了这篇文章: http://martinfowler.com/articles/injection.html 只是想看看我是否做对了。如果
我正在寻找用于 asp.net webapi 的 ioc 容器。我们正在寻找的几个关键功能如下 自定义生命周期 对网络请求生命周期的内置支持 在管理依赖项注册方面与 Web API 的良好集成。 最佳
我很难跟随 FP。当人们说“更惯用的风格”时,我必须明白:99% 的 Java 库不适用于 Kotlin 和 Scala 的 FP 惯用风格,对吧?好吧,我需要 Spring Boot 来快速启动 V
目录 1、Spring 1.1、简介 1.2、优点 1.3、组成 1.4、扩展 2、IO
重要提示:请注意,我并不是说单例具有私有(private)构造函数和静态实例变量(或有人建议使用静态类),而是单例在应用程序生命周期内从控制容器的反转返回相同的实例。 许多容器默认使用较短的生命周期。
Closed. This question needs to be more focused。它当前不接受答案。 想要改善这个问题吗?更新问题,使它仅关注editing this post的一个问题。
松耦合当然很棒,但我经常想知道使用 IoC 容器(例如 CaSTLe Windsor)动态连接的开销对紧耦合系统有什么影响? 我知道详细的答案将取决于 IoC 的用途,但我真的只是想了解 IoC 工作
我正在努力让 IOC 在远程处理场景中工作。我将我的应用程序服务器设置为发布通过 XML 配置的服务(SingleCall)。 众所周知,这就像这样: RemotingConfiguration.Co
我使用 IoC (DI) 方法并且通常有参数,这些参数由最低层(数据库层等)从配置设置(即连接字符串、静态值等)中读取。最好的方法是什么? 直接在这个最底层读取,即: string sendGridA
我是一名优秀的程序员,十分优秀!