#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
зависимости без необходимости делать что-либо, кроме настройки зависимости в корне композиции. Поэтому ни один контроллер никогда не должен будет знать, что контейнер действительно существует.