Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to migrate a static class from .NET to .NET Core?

I am migrating a webform (not a WebForm technology, a stripped down Web Application into a webform functionality) from ASP.NET MVC to ASP.NET Core MVC. My current biggest problem is a static class that we had in the previous version of the webform. This static class uses packages that were available in .NET but not in .NET Core.

I understand that for some of the methods in this static class, I have to use dependency injection to resolve the package problems. However, it is not possible to pass a parameter to a static class making this an "antipattern" for .NET Core.

My Utils.cs static class has only two methods, RenderPartialToString and SendEmail. SendEmail is very simple and has no problems with the current .NET Core packages. However, I have the following code in my static class that does not work with current version.

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 and ConfigurationManager are not available in .NET Core making this static class very difficult to migrate. I believe, I could implement both of these features with dependency injection. However, I do not know how to change this static class so that I can use dependency injection and be able to use these methods in my Controllers.

How can I simply migrate this static class into .NET Core for some dependency injection implementation? Do I need to change all the instances of the Utils class and make it not static?

like image 443
Kemal Tezer Dilsiz Avatar asked Aug 08 '16 15:08

Kemal Tezer Dilsiz


People also ask

How do I migrate a project from .NET to .NET Core?

Move Your Project File You can migrate your old project to the Core project using the 'dotnet migrate; command, which migrates the project. json and any other files that are required by the web application. The dotnet migrate command will not change your code in any way.

Can static class be inherited in C#?

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor. However, they can contain a static constructor.


1 Answers

You should refactor it into an object with non static methods, then register the object with DI services so it can be injected into your controller's constructor or wherever you need it.

I actually have a ViewRenderer class with similar functionality here that I use to generate html email using razor.

I register it with DI like this:

services.AddScoped<ViewRenderer, ViewRenderer>();

Note that my ViewRenderer also has it own constructor dependencies similar to what you need in your static method:

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's constructor dependencies will also be passed into it by dependency injection, so the whole idea is to get away from all the static stuff and let everything be provided by DI.

If I need an instance of ViewRenderer in a Controller I can just add it to the constructor signature of the controller. Actually I don't use it directly in a controller since I use it for email, instead I have an EmailService which depends on ViewRenderer and the controller depends on EmailService

so you want to get to dependency injection all the way down for all dependencies, which is easy if you refactor away from static methods into object instance methods

like image 131
Joe Audette Avatar answered Sep 18 '22 09:09

Joe Audette