Использование IHtmlHelper с внедрением зависимостей - PullRequest
2 голосов
/ 08 марта 2019

Я бы создал контроллер, который отвечает сторонним IHtmlContent, созданным через интерфейс IHtmlHelper, без использования метода View ().На самом деле я использую обходной путь:

Я создал функцию расширения IHtmlHelper, которая ведет себя как «мастер», а другая статическая функция, которая ведет себя как «рабов».Ведущие функции вызывают подчиненные устройства на основе структуры данных, полученной в качестве параметра.Ведомые устройства создают IHtmlContent на основе сторонней библиотеки.Когда все подчиненные функции завершены, контроллер отправляет ответ обратно.Это поведение в представлении cshtml, вызываемом контроллером.

Возможно ли использовать IHtmlHelper в качестве параметра конструктора контроллера с помощью инъекции зависимостей?

Что-то вроде

public class MyTestController 
{
    private readonly IHtmlHelper _html;

    public MyTestController(IHtmlHelper html) {
     _html = html;
    }
}

Если бы это было возможно, я бы упростил многие операции, потому что я использую функции Master / Slave для репликации поведения класса

ЗдесьВы можете найти чистый пример того, как мой код работает сейчас и как я хотел бы изменить его https://gist.github.com/Blackleones/eb0d02b9dd99164271af88e22143d72b#file-example-cs

Мне нужен этот компонент, потому что сторонняя библиотека является расширением IHtmlHelper

Ответы [ 2 ]

1 голос
/ 11 марта 2019

Благодарю Итминуса за ответ.

Однако вызова IHtmlHelper для конструктора контроллера недостаточно, перед его использованием необходимо контекстуализировать IHtmlHelper.

Я хочу поделиться другим решением, которое я нашел, и решить мою проблему, возможно, оно может быть полезным для других пользователей.Пожалуйста, см. https://gist.github.com/Blackleones/eb0d02b9dd99164271af88e22143d72b#file-example-cs, чтобы вспомнить, в чем заключается моя цель.

  1. Чтобы решить мою проблему, я создал класс с именем HtmlHelperAdapter, который содержит несколько нужных мне экземпляров.
public class MyHtmlHelperAdapter
{
        public IHtmlHelper _html;

        public NubessHtmlHelperAdapter(IHtmlHelper html)
        {
            _html = html;
        }

        public IHtmlHelper Html => _html;
        public ViewContext ViewContext => _html.ViewContext;
        public HttpContext HttpContext => _html.ViewContext.HttpContext;
        public ViewDataDictionary ViewData => _html.ViewData;
        public IServiceProvider provider => _html.ViewContext.HttpContext.RequestServices;
}
после этого я создал метод расширения для IHtmlHelper
public static class MyBuilderExtension
{
        public static MyBuilder Nubess(this IHtmlHelper html)
        {
            return new MyBuilder(new MyHtmlHelperAdapter(html));
        }
}

, где MyBuilder равен

public class MyBuilder
    {
        private readonly MyHtmlHelperAdapter _htmlHelper;

        public MyBuilder(MyHtmlHelperAdapter htmlHelper)
        {
            _htmlHelper = htmlHelper;
        }

        public FormBuilder<object> Form<T>(IDictionary<string, string> customizeArgs = null, FormBuilder<object> externalForm = null)
        {
            return new FormBuilder(_htmlHelper, typeof(T), customizeArgs, externalForm).Build();
        }
    }
теперь я могу создавать свое собственное содержимое для представлений, используя class благодаря MyHtmlHelperAdapter
 public class FormBuilder
 {
        private MyHtmlHelperAdapter _htmlHelper;
        private readonly IStringLocalizer<SharedResources> _localizer;
        private readonly LinkGenerator _linkGenerator;
        private readonly IEngine _engine;
        private readonly IEngineElement _element;
        private readonly Type _typeDescriptor;
        private readonly IDictionary<string, string> _descriptorArgs;

        /* variabili per semplificare la gestione del builder */
        private readonly FormBuilder<object> Form;
        private readonly FormConfig Config;
        private readonly IList<FormGroupConfig> Groups;
        private readonly IList<FormItemConfig> Items;
        private readonly IDictionary<string, string> FormOptions;

        private readonly string _clientPrefix = "smtForm_{0}_";

        public FormBuilder(MyHtmlHelperAdapter htmlHelper, Type typeDescriptor, IDictionary<string, string> ModelCustomizeArgs = null, FormBuilder<object> externalForm = null)
        {
            _htmlHelper = htmlHelper;
            _localizer = _htmlHelper.provider.GetRequiredService<IStringLocalizer<SharedResources>>() ?? throw new ArgumentNullException();
            _linkGenerator = _htmlHelper.provider.GetRequiredService<LinkGenerator>() ?? throw new ArgumentNullException();
            _engine = _htmlHelper.provider.GetRequiredService<IEngine>() ?? throw new ArgumentNullException();

            //code..
        }


        public FormBuilder<object> Build()
        {
            //code..
            return Form;
        }

     //methods..
}
1 голос
/ 11 марта 2019

Краткий ответ : Да.


Если вы посмотрите на исходный код MVC , вы обнаружите, что IHtmlHelper зарегистрирован как временный сервис:

    internal static void AddViewServices(IServiceCollection services)
    {

        ...

        //
        // HTML Helper
        //
        services.TryAddTransient<IHtmlHelper, HtmlHelper>();
        services.TryAddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>));
        services.TryAddSingleton<IHtmlGenerator, DefaultHtmlGenerator>();
        services.TryAddSingleton<ModelExpressionProvider>();
        // ModelExpressionProvider caches results. Ensure that it's re-used when the requested type is IModelExpressionProvider.
        services.TryAddSingleton<IModelExpressionProvider>(s => s.GetRequiredService<ModelExpressionProvider>());
        services.TryAddSingleton<ValidationHtmlAttributeProvider, DefaultValidationHtmlAttributeProvider>();

        services.TryAddSingleton<IJsonHelper, DefaultJsonHelper>();

        ...

    }

Другими словами, вы можете добавить сервис IHtmlHelper по своему усмотрению.

В качестве напоминания, мы всегда должны предпочитать использовать IHtmlHelper в View Layer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...