在 ASP.NET 4.6.1 项目中集成 Microsoft.Extensions.DependencyInjection

Posted

技术标签:

【中文标题】在 ASP.NET 4.6.1 项目中集成 Microsoft.Extensions.DependencyInjection【英文标题】:Integrating Microsoft.Extensions.DependencyInjection in ASP.NET 4.6.1 project 【发布时间】:2021-10-21 23:33:05 【问题描述】:

我的大部分项目都使用 .NET Core 3.1,但目前有一个使用 .NET Framework 4.6.1 的现有项目

我在实现对 .NET Framework 4.6.1 的依赖注入时遇到困难,不知道我哪里做错了。

这是我到目前为止所理解和所做的:

.NET Framework 4.6.1 在运行时运行 Global.asax.cs -> Application_Start() .NET Core 3.1 在运行时运行 Startup.cs

这是在 .NET Core 3.1 中添加依赖注入的方式

Startup.cs

    public void ConfigureServices(IServiceCollection services)
    
        services.AddControllers();
        RegisterServices(services);

        ServiceProvider = services.BuildServiceProvider();
    
    private void RegisterServices(IServiceCollection services)
    
        services.AddOptions();
        services.AddTransient<IMemberServices, MemberService>();
    

如何在 .NET Framework 4.6.1 中使用 MemberService 添加 IMemberServices 的依赖项

Global.asax.cs

public class WebApiApplication : System.Web.HttpApplication

    protected void Application_Start()
    
        //What to write here?
    

【问题讨论】:

您可以使用 StructureMap 或 AutoFac 或任何其他容器。 Net 4.7.2 + 原生支持依赖注入。我强烈建议首先更新到这个版本 在 4.7.2 之前的任何版本的 Net 中使用核心都存在错误。 Net 4.7.2 修复了所有错误,使 Core 和 Net 兼容。 @Serge @jdweng 升级到 .NET Framework 4.7.2 后我该怎么做?我尝试使用 .NET Framework 4.7.2 打开一个新项目,但还是做不到。 这能回答你的问题吗? Dependency Injection in .net 4.7? 【参考方案1】:

ASP.NET Web API 实现

警告:此答案在构建 MVC 网站时将起作用。对于 MVC,请看我的其他回答。

假设您正在构建一个 ASP.NET Web API 应用程序,您将必须实现一个自定义 System.Web.Http.Dispatcher.IHttpControllerActivator 并替换您的 Application_Start 事件中的默认值。这是一个完整的工作示例,展示了如何将 Microsoft.Extensions.DependencyInjection (MS.DI) 集成到 ASP.NET Web API 4.6.1 及更高版本中:

using System.Web.Http;
using System.Web.Http.Dispatcher;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Microsoft.Extensions.DependencyInjection;

public class WebApiApplication : System.Web.HttpApplication

    protected void Application_Start()
    
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        var services = new ServiceCollection();

        // Register all your controllers and other services here:
        services.AddTransient<Controllers.ValuesController>();

        var provider = services.BuildServiceProvider(new ServiceProviderOptions
        
            // Prefer to keep validation on at all times
            ValidateOnBuild = true,
            ValidateScopes = true
        );

        GlobalConfiguration.Configuration.Services.Replace(
            typeof(IHttpControllerActivator),
            new MsDiHttpControllerActivator(provider));
    

using System;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
using Microsoft.Extensions.DependencyInjection;

public class MsDiHttpControllerActivator : IHttpControllerActivator

    private readonly ServiceProvider provider;

    public MsDiHttpControllerActivator(ServiceProvider provider)
    
        this.provider = provider;
    

    public IHttpController Create(
        HttpRequestMessage request, HttpControllerDescriptor descriptor, Type type)
    
        var scope = this.provider.CreateScope();
        request.RegisterForDispose(scope);
        return (IHttpController)scope.ServiceProvider.GetRequiredService(type);
    

虽然也可以实现自定义IDependencyResolver 而不是IHttpControllerActivator,但使用控制器激活器更简单,因为您有一个明确的位置来启动新的IServiceScope。创建服务范围并从该范围解析控制器很重要,因为直接从根 IServiceProvider 解析控制器会导致内存泄漏和多线程问题。

【讨论】:

【参考方案2】:

ASP.NET MVC 实现

警告:此答案在构建 Web API 网站时将不起作用。对于 Web API,请参阅我的其他答案。

假设您正在构建一个 ASP.NET MVC 应用程序,您将必须实现一个自定义 System.Web.Mvc.IControllerFactory 并替换您的 Application_Start 事件中的默认值。这是一个完整的工作示例,展示了如何将 Microsoft.Extensions.DependencyInjection (MS.DI) 集成到 ASP.NET MVC 4.6.1 及更高版本中:

using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Microsoft.Extensions.DependencyInjection;

public class MvcApplication : System.Web.HttpApplication

    protected void Application_Start()
    
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        var services = new ServiceCollection();

        // Register all your controllers and other services here:
        services.AddTransient<HomeController>();

        var provider = services.BuildServiceProvider(new ServiceProviderOptions
        
            // Prefer to keep validation on at all times
            ValidateOnBuild = true,
            ValidateScopes = true
        );

        ControllerBuilder.Current.SetControllerFactory(
            new MsDiControllerFactory(provider));
    

using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Extensions.DependencyInjection;

public class MsDiControllerFactory : DefaultControllerFactory

    private readonly ServiceProvider provider;

    public MsDiControllerFactory(ServiceProvider provider) => this.provider = provider;

    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType)
    
        IServiceScope scope = this.provider.CreateScope();

        HttpContext.Current.Items[typeof(IServiceScope)] = scope;

        return (IController)scope.ServiceProvider.GetRequiredService(controllerType);
    

    public override void ReleaseController(IController controller)
    
        base.ReleaseController(controller);

        var scope = HttpContext.Current.Items[typeof(IServiceScope)] as IServiceScope;

        scope?.Dispose();
    

虽然也可以实现自定义IDependencyResolver 而不是IControllerFactory,但使用控制器工厂更简单,因为您有一个明确的位置来开始一个新的IServiceScope。创建服务范围并从该范围解析控制器很重要,因为直接从根 IServiceProvider 解析控制器会导致内存泄漏和多线程问题。

【讨论】:

您好 steven,感谢您的回答,但我的代码是 WebApiApplication 而不是 MvcApplication。我已经更新了问题,希望对您有所帮助。很抱歉有任何困惑 嗨@ZorevGnoz,请参阅我的第二个答案。这显示了一个 Web API 示例。 这很好用,请务必在尝试为其他项目类型实施解决方案之前确定您需要哪种项目类型。

以上是关于在 ASP.NET 4.6.1 项目中集成 Microsoft.Extensions.DependencyInjection的主要内容,如果未能解决你的问题,请参考以下文章

在 Asp.net Web 服务中集成 JWT

在 ASP.NET 中集成支付网关

如何在 ASP.NET MVC 中集成 AngularJS

如何在 asp.net 中集成 Paypal Api 以进行快速结帐?

如何在 ASP.NET MVC 中集成 AngularJS

在 Asp.Net 解决方案中集成 silverlight 控件的最佳实践