我正在使用Microsoft的Unity Framework使用C#。我不太确定如何解决这个问题。这可能与我缺乏统一性理解DI有关。

可以使用以下示例代码来概括我的问题:

class Train(Person p) { ... }

class Bus(Person p) { ... }

class Person(string name) { ... }

Person dad = new Person("joe");
Person son = new Person("timmy");

当我在公共汽车上调用解决方法时,我如何确定注射名称为“ timmy”的人“儿子”,以及当解决火车时,我如何确定那个人的“爸爸”,然后解决名称“乔”?

我想可能使用命名实例?但是我不知所措。任何帮助,将不胜感激。

顺便说一句,我宁愿不创建iPerson界面。

有帮助吗?

解决方案

解决此问题的一种方法是使用带有命名注册的注射构造器。

// 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

其他提示

除非您分别将“ Joe”和“ Timmy”注册为命名依赖项,否则不能确定将“ Timmy”注入了学科。实际上,如果您尝试注册与未命名依赖关系的同一类的两个实例,则您将有一个模棱两可的设置,并且您将无法解决 Person 根本。

通常,如果您必须注册大量命名实例,则可能以错误的方式进行DI。 DI的主要思想是解决 域服务 多于 域对象.

DI的主要思想是提供一种允许您解决的机制 抽象类型 (接口或抽象类) 进入具体类型. 。您的示例没有抽象类型,因此并没有很多意义。

马克·西南(Mark Seeman)做对了。我同情你的困惑。当我学会使用自动依赖性注入容器时,我自己经历了它。问题在于,设计和使用对象有许多有效且合理的方法。然而,只有其中一些方法可与自动依赖注射容器一起使用。

我的个人历史:在我学习如何使用统一或城堡温莎容器等控制容器的反转之前,我就学会了对象构建和控制的原则。我获得了这样写代码的习惯:

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类都是有效的设计。但是第二个是可自动依赖注入的,第一个是不使用的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top