Вопрос

У меня происходит простое зависание при настройке контейнера IoC в отношении следующего типа архитектуры.

В моем приложении есть такие слои (снизу вверх):

  • Проект.Домен
  • Проект.Веб (System.Web.Http и т. д.плюс некоторая базовая логика типа HTTP)
    • В этом проекте есть Базовыйконтроллер
  • Project.MicroServices реализация GET/POST и т. д.в веб-API 2.2.Они наследуются от BaseController в Project.Web и ссылаются на Project.Domain.
  • Проект.Журналирование это моя попытка пересечь журналирование

Когда запрашивается контроллер на уровне MicroServices (GET, POST и т. д.), SimpleInjector использует внедрение свойств для добавления экземпляра ILogger в BaseController.Таким образом, к нему имеют доступ любые контроллеры в проекте MicroServices.Пока это работает хорошо.

Вот моя проблема:

Я хотел бы сделать ведение журнала доступным для всей архитектуры, даже на уровне домена, не нарушая при этом каких-либо сквозных правил и сохраняя развязку.Моя идея, возможно, заключалась в том, чтобы событие, опубликованное на уровне домена, на которое мог подписаться уровень ведения журнала.Но я отвлекся.Чего я не понимаю, так это как заставить SimpleInjector передавать экземпляр Logger в домен (если нужно, мысли?). Это происходит при запуске приложения или только при веб-запросах?Должен ли это быть одноэлементный экземпляр или временный?И как это лучше всего сочетается с Log4Net (возможно, я слишком или недостаточно усложняю свою архитектуру).

Я понимаю, что регистрация происходит при запуске, но как насчет получения экземпляров?Насколько я понимаю, мне следует использовать автоматическое внедрение конструктора, а не использовать Container.GetInstance() для получения экземпляров, но, несмотря на мое обширное чтение, я до сих пор не могу понять, как это работает за пределами запроса веб-API и веб-API SimpleInjector. Расширения.

К тому же, как-то не связанно.Я абстрагирую функциональность Log4Net, но недавно узнал, что, вероятно, не следует этого делать.Учитывая это, хотелось бы получить некоторые рекомендации о том, как все это связано.

Это было полезно?

Решение

Ваше сообщение немного расплывчато и полно вопросов, на которые нелегко ответить без дополнительного контекста, но я сделаю все возможное.

Я хотел бы сделать регистрацию доступными для всей архитектуры, даже в доменном слое

Если у вас есть четкая абстракция для ведения журналов, вы можете сделать эту абстракцию доступной для приложения и вести журналы во всем приложении.

Я абстрагирую функциональность log4net, но недавно я узнал, что, вероятно, не должен.

Я не согласен.Я думаю тебе надо.По возможности не допускайте зависимости ядра вашего приложения от сторонних компонентов, а с помощью ведения журналов это действительно легко сделать.Это легко определить абстракцию что соответствует ТВЕРДЫЙ принципы.И не забывайте, согласно Принцип инверсии зависимостей, абстракция должна быть определяется клиентом.Платформа ведения журналов не может определить необходимую вам абстракцию.

Но будьте уверены, что не попадете в ловушку слишком большого количества журналов, как объяснено. здесь.В большинстве случаев вам не следует вести журнал так часто, а лучше быстро терпеть неудачу и иметь несколько общих фрагментов кода, которые будут вести журнал за вас, вместо того, чтобы вызывать ILogger.Log разбросаны по всей кодовой базе.

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

Я не понимаю, как заставить SimpleInjector передать экземпляр регистрации в домен (если я должен, мысли?)

Есть много мнений по этому поводу.я и Марк Зееманн услуга анемичные модели домена с командами и событиями сверху (или мне разрешено сказать, что мои команды и события становятся моей моделью предметной области?).Другие имеют больше бизнес-логики в своих объектах предметной области.Этим объектам нужны некоторые службы, такие как ILoanCalculator, и вы, вероятно, захотите внедрить зависимости, поскольку позволить этим объектам домена запрашивать службы через Service Location — это очень плохая идея.

Но не забывайте, что это нечто большее, чем просто внедрение конструктора.Для объектов вашего домена вы можете использовать внедрение метода, где службы, необходимые некоторым методам домена, предоставляются как аргументы метода:

public class Loan
{
    public void PayLoan(LoanPeriod periodToPay, ILoanCalculator calculator)
    {
        // ...
    }
}

Поскольку у вас будут классы обслуживания (могу ли я сказать обработчики команд?), которые вызывают эти методы домена, вы можете применить внедрение конструктора к этим классам обслуживания и передать зависимости методу домена.

Я понимаю, что регистрация происходит в стартапе, но как насчет получения экземпляров?

Экземпляры извлекаются (строятся графы объектов) в начале каждого запроса.

Из того, что я понимаю, я должен использовать автоматическую инъекцию конструктора и не использовать intainer.getInstance (), чтобы получить экземпляры

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

Но, несмотря на мое обширное чтение, я до сих пор не могу понять, как это работает вне запроса Web API и расширения SimpleInjector.

Я не уверен, понимаю ли я это.Практически любое приложение основано на запросах, будь то веб-приложение, служба Windows или инструмент командной строки.В веб-приложении запросы поступают из Интернета в виде веб-запросов.В службе Windows у вас есть таймер, который периодически срабатывает, и каждый импульс можно рассматривать как новый запрос (или, возможно, вы используете SqlDependency, и в этом случае возникающее событие является началом нового запроса).Консольное приложение, вероятно, будет иметь только один запрос и вскоре после этого умрет.Для веб-приложений Simple Injector будет неявно контролировать время жизни некоторых служб, тогда как службы Windows и фоновые процессы вам придется контролировать это явно.С помощью простого инжектора Срок службы и ВыполнениеContextScope образы жизни позволяют вам определить явную область, которая контролирует время жизни объектов для такого запроса.А WebApiRequestLifestyle на самом деле использует ExecutionContextScopeLifestyle в фоновом режиме и начинает и завершает область каждого запроса веб-API.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top