【问题标题】:How to migrate a static class from .NET to .NET Core?如何将静态类从 .NET 迁移到 .NET Core?
【发布时间】:2016-08-08 15:44:18
【问题描述】:

我正在将 Web 表单(不是 WebForm 技术,将 Web 应用程序剥离为 Web 表单功能)从 ASP.NET MVC 迁移到 ASP.NET Core MVC。我目前最大的问题是我们在以前版本的网络表单中拥有的静态类。此静态类使用 .NET 中可用但 .NET Core 中不可用的包。

我了解到对于这个静态类中的一些方法,我必须使用依赖注入来解决包问题。但是,无法将参数传递给静态类,使其成为 .NET Core 的“反模式”。

我的 Utils.cs 静态类只有两个方法,RenderPartialToStringSendEmailSendEmail 非常简单,对当前的 .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 类的所有实例并使其不是静态的?

【问题讨论】:

标签: c# asp.net .net asp.net-mvc asp.net-core


【解决方案1】:

您应该使用非静态方法将其重构为一个对象,然后使用 DI 服务注册该对象,以便将其注入控制器的构造函数或您需要的任何地方。

我实际上有一个ViewRenderer class with similar functionality here,我用它来使用剃须刀生成 html 电子邮件。

我像这样向 DI 注册它:

services.AddScoped<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 实例,我可以将其添加到控制器的构造函数签名中。实际上我没有直接在控制器中使用它,因为我将它用于电子邮件,而是我有一个依赖于 ViewRenderer 的 EmailService 并且控制器依赖于 EmailService

所以你希望对所有依赖项都进行依赖注入,如果你将静态方法重构为对象实例方法,这很容易

【讨论】:

    【解决方案2】:

    虽然我会采用@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
        }
    }
    

    【讨论】:

    • 在主执行期间通常不应该有“配置”的概念。 ASP.NET Core 的概念是在初始化期间进行配置,创建一个 IApiService 或其他任何东西,然后通过 DI 使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多