public Interface IFoo()
{
void DoSomething();
}
public class Foo
{
private IFoo _ifoo;
public Foo(IFoo foo)
{
_ifoo = foo;
}
public void Bar()
{
// execute
_ifoo.DoSomething();
}
}
在上面的例子中 - 我通过接口解耦依赖
使用依赖注入VS
在这个场景中,通过使用带静态方法的类紧密耦合的类是什么?
public class Foo
{
public static void GenerateSomeFoo(){
//do something here
}
}
public class FooBar
{
public void Bar()
{
var somevariable = 123;
Foo.GenerateSomeFoo();
}
}
答案 0 :(得分:1)
是通过使用带静态方法的类紧密耦合的类吗?
是的。
在您的示例中,在Foo.GenerateSomeFoo()
类内部调用FooBar
,如果您需要使用替代实现,则更难以交换GenerateSomeFoo()
的实现原因。因此,FooBar
紧密耦合到Foo.GenerateSomeFoo()
。
静态方法本质上与调用它们的代码紧密耦合,因此您应该避免将任何逻辑放在现在或将来接收的静态方法中注入依赖。
然而,这并不意味着你永远不应该使用静态方法。特别是扩展方法非常有用。向它们注入依赖关系只是not very practical,它们往往会使测试变得更加困难。
答案 1 :(得分:0)
关于您使用的命名,您会产生错误混淆。有人希望名为Foo
的类实现接口IFoo
,而不是在IFoo
的构造函数中注入已实现Foo
的对象。
就使用静态方法GenerateSomeFoo
而言,它使代码对测试它没有帮助,因为现在你依赖于具体的实现。
另一种方法是:
// This is the contract.
public interface IFoo
{
void DoSomething();
}
// This is the implementation
public class Foo : IFoo
{
public void DoSomething()
{
// ....
}
}
如果类Foo
需要另一个对象来实现它们的方法,那么可以将它注入到它的构造函数中。例如,假设它需要IBarRepository
。然后,类Foo
将声明如下:
public class Foo : IFoo
{
private readonly IBarRepository _barRepository;
public Foo(IBarRepository barRepository)
{
_barRepository = barRepository
?? throw new ArgumentNullException(nameof(fooRepository));
}
public void DoSomething()
{
// ....
}
}
为什么上述方法更受欢迎?我们假设IBarRepository
的定义如下:
public interface IBarRepository
{
IEnumerable<Bar> GetAll();
}
并且实现此接口的类调用数据库来检索Bar
个对象。使用接口作为依赖关系,您可以使用此接口的模拟非常轻松地测试代码,这是依赖静态类或方法时无法实现的。
答案 2 :(得分:0)
间接是一个战略问题。制定战略意味着您至少对未来想要做的事情有一个远程的想法。从你的简单例子中我无法识别出任何战略意义。
有一句话&#34;世界上没有任何问题无法通过另一层间接解决问题&#34;。你可以把它颠倒过来:即使你没有问题,也可以通过另一层间接解决问题......只是因为你旁边有一把锤子,并不意味着你必须锤击任何东西在你家附近。
使用界面来分离概念当然有帮助。如果您所做的只是调用一个空方法,那也没有意义。