我在构造函数注入方法中需要一些建议依赖注入?

时间:2011-04-03 12:11:18

标签: c# .net oop design-patterns architecture

我对一些建筑方法很感兴趣。我喜欢DI和IOC,但我不理解costructor注入;为什么这么复杂。我编写了下面的代码,它使用了构造函数注入:

namespace DependencyInjection
{
    class Program
    {
        static void Main(string[] args)
        {
            ConstructorInjectionClass myCtx = new ConstructorInjectionClass(new PdfFormat());
            myCtx.Print();
            Console.Read();
        }
    }



    public interface IFormat
    {
        void Print();
    }

    public class PdfFormat : IFormat
    {

        public void Print()
        {
            Console.WriteLine("Pdf Format Print is completed...");
        }
    }


    // Constructor Injection

    public class ConstructorInjectionClass
    {
        private IFormat _format;

        public ConstructorInjectionClass(IFormat format)
        {
               _format = format;
        }

        public void Print()
        {
            _format.Print();
        }
    }

我在下面写了一些代码。我认为这很简单。



    public interface IFormat
    {
        void Print();
    }

    public class PdfFormat : IFormat
    {

        public void Print()
        {
            Console.WriteLine("Pdf Format Print is completed...");
        }
    }

   public interface ISave
    {
        void Add();
    }

    public class Sql: ISave
    {

        public void Add()
        {
            Console.WriteLine("Adding to SQL is completed...");
        }
    }


    // Constructor Injection

    public class ConstructorInjectionClass
    {


        public ConstructorInjectionClass(IFormat format)
        {
               format.Print();
        }

         public ConstructorInjectionClass(ISave saver)
        {
              saver.Add();
        }



为什么要使用构造函数注入?这两种方法的优缺点是什么?

3 个答案:

答案 0 :(得分:4)

第一个例子是构造函数注入。你正在注册班级负责打印到课堂上。

在第二个示例中,您将使用2个参数之一创建一个新类,并使用构造函数中的参数。这有几个原因:

  • 您的构造函数不应该真正做重要的工作,这是在构造函数中保存或打印
  • 您的不同构造者正在做不同的事情。构造函数应该只创建一个新类的实例。
  • 目前尚不清楚不同的构造函数在给出不同的对象时实际会做些什么。
  • 如果您将对象传递给构造函数然后它只是调用它们,为什么不只是让构建此类的代码调用ISaveIPrint实现上的方法。毕竟它必须让它们能够将它们传递给方法。如果你的对象在内部保存它们,那么它们可以在构造对象时提供(比如在你的组合根目录中),并且在你的对象上调用Print的客户端代码不需要知道关于{的事实。存在{1}}和ISave个实现,

构造函数注入是关于你的类要求它在它的构造函数中具有的依赖关系,所以很清楚依赖是什么。通过要求依赖而不是创建它们,测试类变得更简单,因为您可以为测试目的注入模拟依赖项。

第一个选项很好,如果你想添加保存,那么你应该为构造函数添加一个额外的参数来获取IPrint接口以及ISave接口并有一个方法{ {1}}将委托给IPrint implmentation。

通过注入依赖项并通过编程到接口,可以更轻松地在以后更改功能。例如,您可以轻松地对文件进行处理(通过更改传入的Save接口或更改它以保存到xml文件或Web服务,方法是更改​​传递它的ISave实现这使你的课程松散地与保存和打印实现相结合

我会阅读this关于DI / IOC的更多指导的优秀答案

答案 1 :(得分:4)

好吧,与任何模式一样,构造函数注入应该在当且仅当使用它时才使用。你的示例代码有点奇怪......

  • 你的第一个例子就是现场。您的类有一个名为Print的方法,它依赖于另一个类来进行打印。它不需要实例化此依赖项,而是要求在其构造函数中提供依赖项。这是Dependency Inversion Principle的典型示例。基本上:“要求,不要实例化。”
  • 你的第二个例子不太清楚。你班上真的在做什么?这是为了什么?它有两个构造函数对它们的依赖关系执行操作,但为什么呢?该类中没有其他地方依赖于这些类型的实例。那么为什么首先要包装类呢?它似乎比你的第一个例子更加......做作......目前还不清楚代码的架构是如何实现的,因此它不能很好地利用构造函数注入。

答案 2 :(得分:1)

假设您想要注入依赖项...您可以通过构造函数注入或通过属性设置器来执行此操作。我认为构造函数注入的一个优点是IOC使用这种策略。所以,如果你不确定你想去IOC,但你想做DI,那么应该使用构造函数注入来转换到IOC后...更容易......如果你应该改变主意......