代码之家  ›  专栏  ›  技术社区  ›  JP Richardson

C#/Unity中的构造函数注入?

  •  14
  • JP Richardson  · 技术社区  · 16 年前

    我的问题可以用以下示例代码总结:

    class Train(Person p) { ... }
    
    class Bus(Person p) { ... }
    
    class Person(string name) { ... }
    
    Person dad = new Person("joe");
    Person son = new Person("timmy");
    

    我在想也许可以使用命名实例?但我不知所措。任何帮助都将不胜感激。

    3 回复  |  直到 16 年前
        1
  •  19
  •   Daniel Auger    16 年前

    解决这个问题的一种方法是使用带有命名注册的注入构造函数。

    // Register timmy this way  
    Person son = new Person("Timmy");  
    container.RegisterInstance<Person>("son", son);  
    
    // OR register timmy this way  
    container.RegisterType<Person>("son", new InjectionConstructor("Timmy"));  
    
    // Either way, register bus this way.  
    container.RegisterType<Bus>(new InjectionConstructor(container.Resolve<Person>("son")));  
    
    // Repeat for Joe / Train
    
        2
  •  35
  •   Mark Seemann    16 年前

    除非您将“joe”和“timmy”分别注册为命名依赖项,否则您无法确保“timmy”被注入校车。事实上,如果您试图将同一类的两个实例注册为未命名的依赖项,那么您将有一个不明确的设置,并且您将无法解析 Person 完全

    域服务 域对象 .

    DI的主要思想是提供一种机制,允许您解决 抽象类型

        3
  •  15
  •   Paritosh    10 年前

    马克·西曼做对了。我同情你的困惑。当我学会使用自动依赖注入容器时,我自己也经历了这个过程。问题是有许多有效和合理的方法来设计和使用对象。然而,这些方法中只有一些能够与自动依赖注入容器一起工作。

    我的个人经历:在我学会如何使用控制反转容器(如Unity或Castle Windsor容器)之前,我就已经学会了对象构造和控制反转的OO原则。我养成了这样编写代码的习惯:

    public class Foo
    {
       IService _service;
       int _accountNumber;
    
       public Foo(IService service, int accountNumber)
       {
          _service = service;
          _accountNumber = accountNumber;
       }
       public void SaveAccount()
       {
           _service.Save(_accountNumber);
    
       }
    }
    public class Program
    {
         public static void Main()
         {
            Foo foo = new Foo(new Service(),1234);
            foo.Save();
         }
    }
    

    在这个设计中,我的Foo类负责将帐户保存到数据库中。它需要一个帐号来完成这项工作,还需要一个服务来完成这项肮脏的工作。这有点类似于上面提供的具体类,其中每个对象在构造函数中都有一些唯一的值。当您使用自己的代码实例化对象时,这种方法可以很好地工作。您可以在正确的时间传递适当的值。

    然而,当我了解到自动依赖注入容器时,我发现我不再手动实例化Foo。容器将为我实例化构造函数参数。这对像IService这样的服务来说是一个极大的便利。但它显然不能很好地用于整数和字符串等。在这些情况下,它将提供一个默认值(如整数为零)。相反,我习惯于传递特定于上下文的值,如帐号、名称等。。。因此,我不得不调整我的编码和设计风格,使之如下:

    public class Foo
    {
       IService _service;
       public Foo(IService service)
       {
          _service = service;
       }
       public void SaveAccount(int accountNumber)
       {
           _service.Save(accountNumber);
    
       }
    }
    public class Program
    {
         public static void Main()
         {
            Foo foo = new Foo(new Service());
            foo.Save(1234);
         }
    }
    

    这两个Foo类似乎都是有效的设计。但第二种方法可用于自动依赖项注入,而第一种方法则不可用。