Как передать ModelState контроллера моему сервисному конструктору с Autofac?

Это является очевидно языковозависимым. В прошлом с C++ я объявил, что класс тестирования друг класс. К сожалению, это действительно требует, чтобы Ваш производственный код знал о классе тестирования.

5
задан Valentin Vasilyev 30 November 2009 в 08:34
поделиться

1 ответ

На основании ваших комментариев я изменяю свой ответ :)

ModelStateDictionary явно не сервис , который должен разрешаться контейнером, а скорее данные , которые должны быть предоставлены во время создания экземпляра. Мы можем сказать это из того факта, что ModelState принадлежит каждому экземпляру контроллера и, следовательно, недоступен для контейнера во время «разрешения».

Кроме того, каждый экземпляр ModelValidation будет привязан к ] ModelStateDictionary и, таким образом, также должен рассматриваться как данные .

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

Я предлагаю следующее решение:

Поскольку и ModelValidation, и CustomerService требуют данных в своих конструкторах, нам нужны два делегата фабрики (примечание: имена параметров должны соответствовать имена в соответствующем конструкторе):

public delegate IModelValidation ModelValidationFactory(ModelStateDictionary msd);
public delegate CustomerService CustomerServiceFactory(ModelStateDictionary msd);

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

public class EditCustomerController : Controller
{
    private readonly CustomerService _customerService;

    public EditCustomerController(CustomerServiceFactory customerServiceFactory
        /*, ...any other dependencies required by the controller */
          )
    {
        _customerService = customerServiceFactory(this.ModelState);
    }

}

CustomerService должен иметь конструктор, подобный этому (необязательно обрабатывать некоторые из this в классе ServiceBase):

public class CustomerService
{
    private readonly IModelValidation _modelValidation;

    public CustomerService(ModelStateDictionary msd,
              ModelValidationFactory modelValidationFactory)
    {
        _modelValidation = modelValidationFactory(msd);
    }

Чтобы это произошло, нам нужно построить наш контейнер следующим образом:

9
ответ дан 13 December 2019 в 22:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: