Як можна вбудувати залежність від введення залежності? [зачинено]


10

Я трохи роздумував над тим, як ін’єкцію залежності можна краще інтегрувати безпосередньо в мову, схожу на C #. Я придумав потенційне рішення, про яке я хотів би почути вашу думку. Я не використовував багато рамок введення залежності, тому може бути щось, що я не помічаю

У будь-якому випадку ідея полягає в тому, щоб можна було оголосити властивості "ін'єкційними" за допомогою ключового слова. Коли об'єкт інстанціюється, і це властивість не ініціалізується через конструктор або ініціалізатор об'єкта, він запитує екземпляр цього типу властивості від якоїсь глобальної служби.

Аналогічно ви реєструєте обробники для різних типів цієї служби, щоб ви могли створити інстанціювання введеного типу властивості.

Перевага використання такого типу IMO архітектури полягає в тому, що він досить гнучкий і простий у використанні. Мінус полягає в тому, що може виникнути деяка накладна робота із описом до одиночної щоразу, коли ви ініціюєте клас, який має ін'єкцію.

Знову ж таки, це лише проблема для класів, які часто інстанціюються у високопродуктивних рішеннях, тому це не повинно бути великою проблемою. Можливо, ви могли б використовувати якусь фабрику в тих випадках.

Думка, питання, питання, кращі ідеї?

Код

public class SomeClass
{

  public SomeClass()
  {
     //implicit behavior if Animal is not set in constructor or initializer
    this.Animal =  GlobalInjector.Get(this,typeof(Mammal))

  }

  public injectable Mammal Animal  
  {
   get;
   set;
  }
}


 GlobalInjector.Register(typeof(Mammal), () => return new Mammal(someParameter));

Чи можете ви навести приклад псевдокоду для тих із нас, хто не знайомий з DI? PS. Можливо, ви можете відповісти і на моє запитання щодо DI? :)
Стівен

2
Я не впевнений, що отримую. Ви можете отримати все це за допомогою глобального контейнера DI та атрибута "[Injectable]" замість ключового слова, правда?
nikie

Привіт, я спробував трохи написати про DI на ваше запитання, не впевнений, що він відповідає на це, хоча
Homde

nikie: Так, я думаю, ви могли реалізувати власне механізм по-різному, мене більше цікавить, чи лежить в основі логіка
Хомда

Отже, чим відрізняється цей та існуючий IoC, крім вашого додаткового ключового слова?
Метью Віт

Відповіді:


7

Є речі, які належать до мов, і речі, які ні. Здавна C визнав, що IO не належить до мови, оскільки вона зовнішня для обчислювальної моделі і може бути реалізована за допомогою бібліотек функцій.

Ін'єкція залежності залежить від цього. Він зовнішній для мови і може бути реалізований у відповідних рамках.

Однією із проблем сучасних мов є те, що вони намагаються зробити занадто багато. Врешті-решт ці мови руйнуються під власною вагою, оскільки програмісти біжать до більш простих мов.


Я погоджуюсь в теорії, ви не можете мати мову, де кожна функція є особливістю мови, не роздуваючи її. Однак завжди є можливість для нових вищих абстракцій, що допомагає нам писати кращий код. Можливо, введення залежності як таке не є проблемою, яку потрібно вирішити, але проблема, яку вона вирішує, а саме спосіб полегшити нам зменшення залежностей. Це, мабуть, не найкращий спосіб це зробити :)
Хомде

5

Це не потрібно

Одне з речей, які мені найбільше подобаються у найкращих структурах DI, які я використав, - це те, що код конфігурації верхнього рівня є єдиною частиною вашого коду, яку потрібно знати про DI. Автоматичне підключення проводів здійснюється на рівні контейнера та конфігурації / "завантаження модулів", і ваш код програми може бути повністю забутий про це.

Це означає, що немає атрибутів, ніяких магічних рядків, немає умовності Кожен фрагмент коду знає лише те, що він приймає код у своєму конструкторі (/ властивості / методи), і це все.

З таким дизайном вам зовсім не потрібно змінювати мову, щоб підтримувати введення залежності.

Це потенційно небезпечно

Чого я найбільше побоююся щодо системи ін’єкцій залежностей від мови, це те, що це створить бар'єр проти будь-якої іншої реалізації, але, мабуть, вона перетвориться на куточок у якомусь аспекті.

Деякі способи, як він міг намалювати себе в кут:

  • Підтримує лише конфігурацію на основі XML або лише конфігурацію на основі коду
  • Не в змозі чітко підтримувати модель дизайну заводу (не лише перехідні компоненти: компоненти, що генеруються під час роботи)
  • Якось змінивши свій код, тому я змушений був використовувати ін'єкцію залежності, і я не міг просто створити свій клас для одиничних тестів
  • Не підтримує користувальницькі життєві цикли
  • Не є розширюваним
  • Не підлягає заміні у випадках, коли мені потрібна більша налаштування
  • Будучи зламаним якимось чином, який ми ще не розуміємо, тому що ми. Чисті користувачі не використовували DI досить довго, щоб знати підводні камені

4

Ви бачили Рамку керованого розширення, що постачається разом з .NET 4? Ось стаття, яку я написав з кількома прикладами. В основному це форма введення залежності, вбудована в .NET, з додатковими функціями розкриття часу виконання.

Ін'єкції властивостей виглядають приблизно так:

class Program
{
    [Import]
    public IMessageSender MessageSender { get; set; }
}

Ін'єкції конструктора виглядають приблизно так:

class Program
{
    [ImportingConstructor]
    public Program(IMessageSender messageSender) 
    {
    ...
    }
}

Ви можете імпортувати поля, робити необов'язковий імпорт, імпортувати колекції послуг, у тому числі робити ледачий імпорт з метаданими, щоб ви могли шукати відповідну службу для інстанції. Ви навіть можете повторно імпортувати під час виконання, щоб шукати нові розширення.


Хоча MEF дуже здорово для плагінів, я не думаю, що я хотів би використовувати його як загальний механізм DI
Хом

1
@MKO - Чи можете ви детальніше розглянути те, чого не вистачає? Мені відомо про всі статті, де Гленн Блок змагається, щоб запевнити людей, що MEF не замінить усі рамки DI, але якщо ви подивитесь на деталі, очевидно, що це більше політичне твердження, ніж будь-що інше. Однак, якщо ви зможете дати хороший перелік функцій, яких не вистачає MEF порівняно з іншими рамками DI, це допоможе людям прийняти обґрунтоване рішення. Крім того, питання стосується рамки DI в C #, а MEF - це очевидно контейнер DI в рамках .NET.
Скотт Вітлок

2
  1. Ви дійсно не описуєте механізм налаштування, який IMHO є складним бітом. Як змусити весь код, що працює в одному потоці, використовувати з'єднання DB, а весь код в іншому потоці з'єднання B? Як заблокувати введення певного ресурсу, оскільки користувач, який зараз увійшов, не має доступу до нього?
  2. Не використовуйте глобальний інжектор. Ніколи не використовуйте жодної глобальної речі, інакше ви можете використовувати глобальні змінні. Ні, використання OOP-говорів, таких як одиночні або "статичні" замість глобальних, не змінює їх глобальну природу.
  3. Розглянемо контейнер з динамічним діапазоном. Незважаючи на те, що лексичне оцінювання справедливо перемогло проти динамічного масштабування, я вважаю, що динамічний обсяг стане чудовою заміною глобальної сфери. Диференціальне успадкування було б приємною реалізацією (як, наприклад, спадкування на основі прототипу).
  4. Я вважаю, що механізм DI, призначений для використання мови, повинен бути справді простим, жоден з цих корпоративних речей, що є нормою для C # та Java. Динамічний механізм оцінювання з простим конфігураційним шаром зверху може зробити цю справу. Підприємницькі рішення можуть бути розшаровані сторонніми сторонами.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.