Вопрос

Я использую C# с Microsoft Unity Framework. Я не совсем уверен, как решить эту проблему. Вероятно, это как -то связано с моим отсутствием понимания DI с единством.

Моя проблема может быть суммирована с помощью следующего примера кода:

class Train(Person p) { ... }

class Bus(Person p) { ... }

class Person(string name) { ... }

Person dad = new Person("joe");
Person son = new Person("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

Другие советы

Если вы не зарегистрируетесь соответственно «Джо» и «Тимми» как именованные зависимости, вы не можете быть уверены, что «Тимми» вводится в Schoolbus. На самом деле, если вы попытаетесь зарегистрировать два экземпляра того же класса, что и неназванные зависимости, у вас будет неоднозначная установка, и вы не сможете разрешить Person вообще.

В общем, если вам нужно зарегистрировать много названных экземпляров, вы, вероятно, выступаете с DI неправильно. Основная идея DI - решить Доменные услуги больше, чем Доменные объекты.

Основная идея DI - предоставить механизм, который позволяет вам разрешить Абстрактные типы (Интерфейсы или абстрактные классы) в конкретные типы. Анкет Ваш пример не имеет абстрактных типов, поэтому он не имеет большого смысла.

Марк Симан понял это правильно. И я сочувствую твоей путанице. Я сам прошел через это, когда научился использовать автоматические контейнеры впрыскивания зависимости. Проблема в том, что существует много достоверных и разумных способов разработки и использования объектов. Тем не менее, только некоторые из этих подходов работают с автоматическими контейнерами инжекторионов зависимости.

Моя личная история: я выучил принципы построения объектов и инверсию контроля задолго до того, как узнал, как использовать инверсию контрольных контейнеров, таких как контейнеры Unity или Windsor Windsor. Я приобрел привычку писать код таким образом:

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