c# Как избежать безумства конструктора конструкции зависимостей?



4 Answers

Я не думаю, что у ваших конструкторов классов должна быть ссылка на ваш контейнерный период IOC. Это представляет собой ненужную зависимость между вашим классом и контейнером (тип зависимости, который МОК пытается избежать!).

c# java dependency-injection inversion-of-control ioc-container

Я считаю, что мои конструкторы начинают выглядеть так:

public MyClass(Container con, SomeClass1 obj1, SomeClass2, obj2.... )

с постоянно увеличивающимся списком параметров. Поскольку «Контейнер» является контейнером для инъекций, почему бы просто не сделать это:

public MyClass(Container con)

для каждого класса? Каковы недостатки? Если я это сделаю, мне кажется, что я использую прославленную статику. Пожалуйста, поделитесь своими мыслями о безумии безумства в IoC и Dependency Injection.




Я столкнулся с подобным вопросом о зависимостях Injection от конструктора и о том, насколько сложным он передавался во всех зависимостях.

Одним из подходов, который я использовал в прошлом, является использование шаблона фасада приложения с использованием уровня сервиса. У этого был бы грубый API. Если эта услуга зависит от репозиториев, она будет использовать инсталляцию setter для частных свойств. Для этого требуется создание абстрактной фабрики и перемещение логики создания хранилищ на фабрику.

Подробный код с пояснениями можно найти здесь

Рекомендации по IoC в сложном сервисном слое




Это подход, который я использую

public class Hero
{

    [Inject]
    private IInventory Inventory { get; set; }

    [Inject]
    private IArmour Armour { get; set; }

    [Inject]
    protected IWeapon Weapon { get; set; }

    [Inject]
    private IAction Jump { get; set; }

    [Inject]
    private IInstanceProvider InstanceProvider { get; set; }


}

Вот грубый подход, как выполнить инъекции и запустить конструктор после инъекции значений. Это полностью функциональная программа.

public class InjectAttribute : Attribute
{

}


public class TestClass
{
    [Inject]
    private SomeDependency sd { get; set; }

    public TestClass()
    {
        Console.WriteLine("ctor");
        Console.WriteLine(sd);
    }
}

public class SomeDependency
{

}


class Program
{
    static void Main(string[] args)
    {
        object tc = FormatterServices.GetUninitializedObject(typeof(TestClass));

        // Get all properties with inject tag
        List<PropertyInfo> pi = typeof(TestClass)
            .GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
            .Where(info => info.GetCustomAttributes(typeof(InjectAttribute), false).Length > 0).ToList();

        // We now happen to know there's only one dependency so we take a shortcut just for the sake of this example and just set value to it without inspecting it
        pi[0].SetValue(tc, new SomeDependency(), null);


        // Find the right constructor and Invoke it. 
        ConstructorInfo ci = typeof(TestClass).GetConstructors()[0];
        ci.Invoke(tc, null);

    }
}

В настоящее время я работаю над хобби-проектом, который работает так: https://github.com/Jokine/ToolProject/tree/Core




Инъекция контейнера - это ярлык, который вы в конце концов пожалеете.

Над инъекцией не проблема, она обычно является симптомом других структурных недостатков, в первую очередь разделение проблем. Это не одна проблема, но может иметь много источников, и что затрудняет ее исправление, так это то, что вам придется иметь дело со всеми из них, иногда в одно и то же время (подумайте о распутывающих спагетти).

Вот неполный список вещей, которые нужно искать

Плохая структура доменов (Совокупный корень ... и т. Д.)

Плохое разделение проблем (состав услуг, команды, запросы) См. CQRS и Event Sourcing.

ИЛИ Mappers (будьте осторожны, эти вещи могут привести вас к неприятностям)

Просмотрите модели и другие DTO (не используйте их повторно и старайтесь держать их на минимальном уровне !!!!)




Related