C# Расширение базового класса из плагина без репликации аргументов конструктора - PullRequest
0 голосов
/ 07 апреля 2020

Я создаю приложение с поддержкой плагинов. У меня есть основная часть функциональности, которая может или не может быть расширена с помощью плагинов. Итак, основная идея c выглядит следующим образом:

interface IFoo {
   void PerformFoo();
}

class CoreFoo {
    CoreFoo(Dependency1 dep1, [SomeDependencyInjectionAttribute] Dependency2 dep2) {
        // assign to fields
    }

    void PerformFoo() {
        this.Bar();
        // other actions
    }

    protected virtual void Bar() {
        // Do bar
    }    
}

class PluginFoo : CoreFoo {
    PluginFoo(Dependency1 dep1, [SomeDependencyInjectionAttribute] Dependency2 dep2, PluginDependency dep3) 
        : base(dep1, dep2) 
    { /* assign to fields */ }

    protected override void Bar() {
        // Do changed bar
    }
}

Проблема, с которой я сталкиваюсь, заключается в том, что PluginFoo тесно связан с конструктором CoreFoo и должен будет реплицировать все аргументы, чтобы правильно их внедрить. Поэтому любое изменение конструктора CoreFoo нарушит совместимость PluginFoo. Как этого избежать?

Я могу представить себе полусредное решение для внедрения зависимостей как некоторый класс DependencyBundle, который я могу изменить, не касаясь класса PluginFoo, например:

class FooDependencyBundle {
    FooDependencyBundle(Dependency1 dep1, [SomeDependencyInjectionAttribute] Dependency2 dep2) {
        // assign to properties
    }
}

class CoreFoo {
    CoreFoo(FooDependencyBundle deps) {
        // assign to fields
    }

    // ... implementation  
}

Но кажется, что это неправильно. Есть ли лучшие?

1 Ответ

0 голосов
/ 07 апреля 2020

U может создать что-то вроде сервиса toolbox и внедрить его в конструктор Core. Затем, если вы хотите добавить что-то новое в функциональность Core, добавьте зависимость в toolbox, и вам не нужно ничего менять в конструкторе Core или классе плагинов.

class CoreFoo {
    CoreFoo([SomeDependencyInjectionAttribute] DependencyToolboxService service) {
        // assign to fields
    }

    void PerformFoo() {
        this.Bar();
        // other actions
    }

    protected virtual void Bar() {
        // Do bar
    }    
}

class PluginFoo : CoreFoo {
    PluginFoo([SomeDependencyInjectionAttribute] DependencyToolboxService service, PluginDependency dep3) 
        : base(service) 
    { /* assign to fields */ }

    protected override void Bar() {
        // Do changed bar
    }
}

Сервис Toolbox может выглядеть как


public class DependencyToolbox : IToolbox
{
     public readonly Dependency Dependency1;

     public DependencyToolbox(Dependency dependency1, //Other services,dependencies//)
     {
         Dependency1 = dependency1;
     }
}
...