在一些情况下,我最常使用"混蛋注射".当我有一个"适当的"依赖注入构造函数时:
public class ThingMaker {
...
public ThingMaker(IThingSource source){
_source = source;
}
Run Code Online (Sandbox Code Playgroud)
但是,对于我打算作为公共API(其他开发团队将使用的类)的类,我永远找不到比编写具有最可能需要的依赖项的默认"bastard"构造函数更好的选择:
public ThingMaker() : this(new DefaultThingSource()) {}
...
}
Run Code Online (Sandbox Code Playgroud)
这里明显的缺点是,这会对DefaultThingSource产生静态依赖; 理想情况下,没有这种依赖性,消费者总是会注入他们想要的任何IThingSource.但是,这太难用了; 消费者希望新建一个ThingMaker并开始制作物品,然后几个月后,在需要时注入其他东西.在我看来,这只留下了几个选项:
男孩,#3肯定看起来很有吸引力.还有另一种更好的选择吗?#1或#2似乎不值得.
这是设置.假设我有一些需要服务实例的动作过滤器:
public interface IMyService
{
void DoSomething();
}
public class MyService : IMyService
{
public void DoSomething(){}
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个需要该服务实例的ActionFilter:
public class MyActionFilter : ActionFilterAttribute
{
private IMyService _myService; // <--- How do we get this injected
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
_myService.DoSomething();
base.OnActionExecuting(filterContext);
}
}
Run Code Online (Sandbox Code Playgroud)
在MVC 1/2中,将依赖关系注入动作过滤器是一个痛苦的屁股.最常见的方法是使用自定义操作调用因为在这里可以看到:http://www.jeremyskinner.co.uk/2008/11/08/dependency-injection-with-aspnet-mvc-action-filters/的这种解决方法背后的主要动机是因为以下方法被认为是与容器的草率和紧密耦合:
public class MyActionFilter : ActionFilterAttribute
{
private IMyService _myService;
public MyActionFilter()
:this(MyStaticKernel.Get<IMyService>()) //using Ninject, but would apply to any container
{
}
public MyActionFilter(IMyService myService)
{
_myService = myService;
} …Run Code Online (Sandbox Code Playgroud) c# asp.net-mvc dependency-injection actionfilterattribute asp.net-mvc-3
似乎每个人都在转向IoC容器.我曾试图"摸清"它一段时间,尽管我不想成为一个在高速公路上走错路的司机,但它仍然没有通过常识测试.让我解释一下,如果我的论点存在缺陷,请纠正/启发我:
我的理解:IoC容器应该在组合不同组件时让您的生活更轻松.这可以通过a)构造函数注入,b)setter注入和c)界面注入来完成.然后以编程方式或在容器读取的文件中"连接"它们.然后按名称召唤组件,然后在需要时手动投射.
我得不到的:
编辑 :( 更好的措辞) 为什么使用一个不是语言惯用的不透明容器,如果组件设计得当(使用IoC模式,松散耦合),你可以用更简洁的方式"连接"应用程序(imho) ?这个"托管代码"如何获得非平凡的功能?(我听过一些关于生命周期管理的提及,但我不一定能理解这比自己动手更好/更快.)
ORIGINAL:为什么要将所有组件存储在一个容器中,以与语言惯用的方式"连接起来",在按名称调用组件时使用相当于"goto labels"的东西,然后通过手动转换失去静态类型语言的许多安全优势,当你通过不执行它获得等效功能时,而是使用现代OO语言给出的所有很酷的抽象功能,例如编程到接口?我的意思是,实际上需要使用组件的部件必须知道它们在任何情况下都在使用它,并且在这里你将使用最自然,惯用的方式进行"连线" - 编程!
IoC = 控制反转
DIP = 依赖倒置原理(SOLID 中的 D)
IoC == DIP?我想是这样的,确实如此。
构建软件的世界已经如此混乱,为什么还要用这么多词来表达同样的事情呢?
(我知道DI (依赖注入),它与DIP和IoC不同)
更新:
根据答案,我们可以说: ( DI ) + ( IoC ) = (依赖倒置原理) ?
我有一个C#类,它自己实例化一个NetworkCommunicator类.我想模拟NetworkCommunicator我的单元测试类,并用一个非常简单的存根替换它.
但NetworkCommunicator它永远不会作为参数传递.它是由被测试的类创建的.
在Ruby中,这很容易被模拟出来.在Java中,这就是你需要依赖注入的原因,这对于这个项目来说太重了.有没有一种简单的方法可以在C#中模拟它,也许使用Moq或类似的东西?
注入/隔离密封在dll中并且不实现接口的类的首选方法是什么?
我们使用Ninject.
假设我们有一个类"Server",我们想要注入/隔离"Server"使用的类TcpServer.
不想太具体,因为我想知道最好的方法,但让我们这样说:
public class Server
{
IServer _server;
public Server(IServer server)
{
_server = server;
}
public void DoSomething()
{
_server.DoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
_server 在测试的情况下,应该注入TcpClient或mock
我有个问题。我有一些 OOP 经验,但我对 PHP(OOP) 很陌生。我正在努力学习它。是否可以重载构造函数?
在其他语言中可以重载构造函数,但在 php 中不行吗?我尝试过,但我从 IDE 收到以下消息:“此类中已定义具有相同名称的方法”
class testClass{
public $param1 = "";
public $param2 = "";
public function __construct($param1, $param2){
$this->param1 = $param1;
$this->param2 = $param2;
}
public function __construct($param1){
$this->param1 = $param1;
//ToDO use function to set param2
}
}
Run Code Online (Sandbox Code Playgroud) c# ×4
.net ×2
oop ×2
asp.net-mvc ×1
constructor ×1
mocking ×1
moq ×1
ninject ×1
php ×1
terminology ×1
unit-testing ×1