Использование простого инжектора с базовыми классами

#c# #.net #dependency-injection #simple-injector

#c# #.net #внедрение зависимостей #простой инжектор

Вопрос:

Я пытаюсь выяснить, как правильно использовать простой инжектор и внедрение зависимостей.

У меня есть MasterController и несколько контроллеров, которые работают под этим. Итак, в основном то, что я пытаюсь архивировать MasterController , я могу использовать из других классов или, возможно, из моего пользовательского интерфейса.

 public class MasterController
{
    public static Container _container = new Container();

    ILogger logger;

    public IMainController MainController;
    public ISubController SubController;

    public MasterController()
    {
        _container.Register<ILogger, DebugLogger>(Lifestyle.Singleton);
        _container.Register<IMainController, TestController>(Lifestyle.Singleton);
        _container.Register<ISubController, Test2Controller>(Lifestyle.Transient);

        _container.Verify();

        logger = _container.GetInstance<ILogger>();
        MainController = _container.GetInstance<IMainController>();
    }

    public void RenameMainController(string _name)
    {
        MainController.Name = _name;
    }

    // more code here.
}
  

Тогда у меня есть мои IMainController , ISubController , TestController и Test2Controller .

 public interface IMainController
{
    string Name { get; set; }
    void DoSomething();
}

public interface ISubController
{
    string Name { get; set; }
    void DoSomething();
    void SomeExtraFunctionality();
}

public class TestController : BaseController, IMainController
{
    private ILogger logger;

    public List<ISubController> SubControllers = new List<ISubController>();

    public TestController(ISubController _SubController, ILogger _logger)
    {
        logger = _logger;

        SubControllers.Add(_SubController);
        logger.Log("TestController ready");
    }

    public void DoSomething() { }
}

public class Test2Controller : BaseController, ISubController
{
    private ILogger logger;

    public Test2Controller(ILogger _logger)
    {
        logger = _logger;
        logger.Log("TestController ready");
    }

    public void DoSomething() { }
    public void SomeExtraFunctionality() { }
}
  

Моя идея заключается в том, что у меня мало контроллеров, и они используют некоторые общие вещи из BaseController

 public class BaseController
{
    public string Name { get; set; }

    // here is some code. 
}
  

Но BaseController я также хочу использовать ILogger. Как мне сделать это правильно?

Теперь я добавил BaseController в контейнер.

 _container.Register<BaseController>(Lifestyle.Transient);
  

А затем добавление конструктора в BaseController

     public BaseController(ILogger _logger)
    {
        logger = _logger;
    }
  

А затем добавьте

 : base(_logger) 
  

после всех конструкторов контроллера Пример:

 public TestController(ISubController _SubController, ILogger _logger) : base(_logger)
  

Но правильный ли это способ сделать это или есть более «правильный» способ сделать это?

Комментарии:

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

Ответ №1:

Вы следили за документами? Использование простого инжектора

Даже ваш главный контроллер не должен знать о контейнере, и контейнер не должен быть широко доступен через приложение. Лучше создать и настроить ваш контейнер в корневом каталоге вашего приложения, т.Е. Где-то рядом Application_Start с документацией Simple Injector, и не предоставлять этот контейнер остальной части вашего приложения. В противном случае вы фактически получаете анти-шаблон Service Locator.

В рамках конфигурации вы можете настроить простой инжектор для PerWebApiRequest образа жизни (при условии, что вы используете MVC или выбираете подходящую альтернативу), и контейнер автоматически введет зависимости в любой конструктор контроллера и удалит IDisposable зависимости без необходимости делать что-либо, кроме настройки зависимости в корне композиции. Поэтому ни один контроллер никогда не должен будет знать, что контейнер действительно существует.