适用于小型.NET项目的IoC / DI

时间:2011-09-16 09:49:54

标签: c# .net dependency-injection inversion-of-control

IoC / DI框架提供的关注点的分离对于大型项目来说不容小觑,但在小型项目中是否存在这种技术的位置?

当您编写另一个小型/平均项目时,您能否分享一些您认为有用的IoC / DI框架的实际用途。

为了定义:

“小项目”包含100-1000行代码(balpark,只是为了给出一个想法),代码需要1-3天,生成的应用程序在被丢弃或退出之前的生命周期内1周 - 初始发布后的5年(这是很难在小型/平均/大型项目之间画一条线)。

感谢。

6 个答案:

答案 0 :(得分:11)

对于一个小项目,我很想继续使用依赖注入,但不使用框架。只需在入口点处制作所有依赖项。您仍然可以获得可测试性的所有好处,并且您可以在以后继续使用完全成熟的容器 - 但您不必担心设置容器,直到它实际上有用。

我在几个小项目中使用过这种方法,而且效果非常好。当然,这取决于你的依赖是多么复杂 - 他们是否需要工厂,有不同的范围等 - 但如果它只是“我有这三件事都依赖于身份验证服务”那么那就非常简单。

答案 1 :(得分:7)

  

但是在一个小项目中是否有这样的技术的地方?

即使在小型项目中,您也应该使用IoC模式来削弱层之间的耦合并使其可单元测试。始终使用抽象。您是否使用DI框架并不重要。在小项目中,您可以简单地手动执行依赖项的管道,不需要对象容器来执行依赖项注入,但是当您再次考虑它时,为什么不呢?

答案 2 :(得分:6)

取决于您认为在实施中重要的内容。如果可测试性很重要,并且如果您倾向于遵循单一责任原则(在小型或大型项目中),那么您通常会得到比您可能更多的类。这可能会导致像

这样的调用
var svc = new ShippingService(new ProductLocator(), 
                              new PricingService(), 
                              new InventoryService(), 
                              new TrackingRepository(new ConfigProvider()), 
                              new Logger(new EmailLogger(new ConfigProvider())));

如果你可以忍受这个,我个人也会这样,在一个扔掉的应用程序,然后无论如何你真的不需要一个DI容器。去做任何让你快乐的事情。欢呼声。

修改

多年来,我发现TinyIoC对于小型项目来说是一个很好的妥协。

答案 3 :(得分:1)

我不会将IoC与项目规模联系起来:

  • 项目中的课程数量
  • 依赖的复杂性
  • 预期的维护和扩展量
  • 预期在扩展和维护期间切换开发人员

特别是最后两个会让你更容易测试你需要的代码(使用适当的工具可以避免它......)IoC。

不要过度设计代码

因此我建议不要将DI容器用于初学者,但绝对使用IoC 的接口和双构造器如:

public class Example : IExample // for others that might depend on it
{
    private IDependant service;

    // default constructor used in your application
    public Example() : this(new DependentService())
    {
        // does nothing else
    }

    // constructor for testing purposes
    public Example(IDependant service)
    {
        this.service = service;
    }

    // IExample implementation
}

在不使用DI容器的情况下,可以轻松地手动管理简单的两级依赖关系。并且最有可能更快地使用。这将使您的代码易于测试,尤其是如果您将提供错误作为测试用例,可以自动防止面向未来的错误。

小项目往往会增长

在商业环境中具有附加价值的小型项目往往会频繁扩展,因为它会激发用户的想象力,甚至可以进一步提高内容。所以不要低估你的小型项目。它可能很快就会成长。

答案 4 :(得分:1)

我写了很多类似规模的项目,每年30-40个。

我使用DI但是使用Resolve方法创建我自己的工厂类。

public T Resolve<T>()
    where T:class {
        if (typeof(T).IsAssignableFrom(typeof(Something)))
            return new Something(Resolve<ISomethingElse>()) as T;
        ...
}

我采取的一个捷径是,我将大多数成员设为虚拟,而不是创建单独的界面。

答案 5 :(得分:0)

一般来说,为什么不将DI容器用于小型项目?你的代码库越简单,使用容器就越简单,我的建议就是使用它提供了一个简单的流体接口来进行依赖注册,或者只是使用linq,那么你最后会得到一个非常小的占用空间来连接你的整个应用程序:

public void OnStartup(args){
    var container = new IoCContainerOfChoice();

    Types.FromThisAssembly()
        .ForEach(type => container.Register(type, type.DefaultInterface());

    container.Resolve<ShellView>();
}

对于许多小项目来说,这很简单。这个想法是一个单行程序,它使用默认接口注册项目中的所有类型(我通常在“System.Type”上编写一个扩展方法来选择一个命名接口,第一个接口,或者只返回它自己)。注意:大多数现代IoC容器都有自己的Fluent接口来提供此功能,这只是一个例子。

嘿,看,你现在正在为意外增长的未来做好准备,你可以节省一大堆“新的”,并将你的应用程序大大或小分离。