Как перенести статический класс с .NET на .NET Core?

Я переношу веб-форму (а не технологию WebForm, усеченное веб-приложение в функциональность веб-формы) из ASP.NET MVC в ASP.NET Core MVC. Моя самая большая проблема - это статический класс, который у нас был в предыдущей версии веб-формы. Этот статический класс использует пакеты, которые были доступны в .NET, но не в .NET Core.

Я понимаю, что для некоторых методов в этом статическом классе я должен использовать инъекцию зависимостей для решения проблем с пакетом. Тем не менее, невозможно передать параметр статическому классу, сделав это "антипаттерн" для .NET Core.

Статический класс My Utils.cs имеет только два метода: RenderPartialToString и SendEmail. SendEmail очень прост и не имеет проблем с текущими пакетами .NET Core. Однако у меня есть следующий код в моем статическом классе, который не работает с текущей версией.

public static class Utils
 {
 public static readonly string ApiUrl = ConfigurationManager.AppSettings["ApiUrl"];
 public static readonly string ApiKey = ConfigurationManager.AppSettings["ApiKey"];
 public static string RenderPartialToString(Controller controller, string viewName, object model)
 {
 controller.ViewData.Model = model;
 using (StringWriter sw = new StringWriter())
 {
 ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
 ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
 viewResult.View.Render(viewContext, sw);
 return "document.write('" + sw.GetStringBuilder().Replace('\n', ' ').Replace('\r', ' ').Replace("'","\\'").ToString() + "');";
 }
 }
 ...
 }

ViewEngine и ConfigurationManager недоступны в .NET Core, поэтому этот статический класс очень трудно переносить. Я считаю, что я мог бы реализовать обе эти функции с помощью инъекции зависимостей. Тем не менее, я не знаю, как изменить этот статический класс, чтобы я мог использовать инъекцию зависимостей и иметь возможность использовать эти методы в моих контроллерах.

Как я могу просто перенести этот статический класс в .NET Core для какой-либо реализации внедрения зависимостей? Мне нужно изменить все экземпляры класса Utils и сделать его не статическим?

2 ответа

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

У меня действительно есть класс ViewRenderer с аналогичной функциональностью здесь, который я использую для генерации html-сообщения с помощью бритвы.

Я зарегистрирую его с помощью DI следующим образом:

services.AddScoped<viewrenderer, viewrenderer="">();
</viewrenderer,>

Обратите внимание, что мой ViewRenderer также имеет собственные зависимости конструктора, похожие на то, что вам нужно в вашем статическом методе:

public ViewRenderer(
 ICompositeViewEngine viewEngine,
 ITempDataProvider tempDataProvider,
 IActionContextAccessor actionAccessor
 )
 {
 this.viewEngine = viewEngine;
 this.tempDataProvider = tempDataProvider;
 this.actionAccessor = actionAccessor;
 }
 private ICompositeViewEngine viewEngine;
 private ITempDataProvider tempDataProvider;
 private IActionContextAccessor actionAccessor;

Зависимости конструктора ViewRenderer также будут переданы в него путем инъекции зависимостей, поэтому вся идея состоит в том, чтобы уйти от всех статических материалов и позволить всем предоставлять DI.

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

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


Хотя я бы пошел с помощью @Joe, может быть другой способ для вашего дела. Чтобы использовать метод расширения контроллера:

// register configuration
public void ConfigureServices(IServiceCollection services)
{
 services.AddSingleton<iconfiguration>(Configuration);
}
public static class ControllerExtension
{
 public static string RenderPartialToString(this Controller controller, string viewName, object model)
 {
 controller.ViewData.Model = model;
 var config = controller.HttpContext.RequestServices.GetService<iconfiguration>();
 // other stuff
 }
}
</iconfiguration></iconfiguration>

licensed under cc by-sa 3.0 with attribution.