簡體   English   中英

第一次嘗試在 WebAPI 中實現依賴注入

[英]Trying to implement Dependency Injection into WebAPI for the first time

我有一個解決方案,其中包含單獨的項目接口中的 WebAPI、BL 和 DAL 層,這些項目針對.Net 4.8,我第一次嘗試實現依賴注入。

我沒有使用任何外部 IoC 包 StructureMap、Autofac 等,實際上我正在做的唯一注入是在層之間。

我一直在關注這個以前的stackoverflow問題

但是,我已經陷入困境。

這是我的startup.cs:

using TA.Services.WebAPI.Providers;

using System.Web.Http.Dependencies;
using Microsoft.Extensions.DependencyInjection;

using System.Linq;
using System.Web.Mvc;
using TA.Services.BL.BusinessLogic;
using TA.Services.BL.Interface;

[assembly: OwinStartup(typeof(TA.Services.WebAPI.Startup))]
namespace TA.Services.WebAPI
{
  public class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      var services = new ServiceCollection();
      ConfigureServices(services);
      var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());

      HttpConfiguration config = new HttpConfiguration();

      config.DependencyResolver = resolver;

      ConfigureOAuth(app);

      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
      app.UseWebApi(config);

    }

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
          .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
          .Where(t => typeof(IController).IsAssignableFrom(t)
                      || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
    }

    public void ConfigureOAuth(IAppBuilder app)
    {
      OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
      {
        AllowInsecureHttp = true,
        TokenEndpointPath = new PathString("/token"),
        AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
        Provider = new SimpleAuthorizationServerProvider()
      };

      // Token Generation
      app.UseOAuthAuthorizationServer(OAuthServerOptions);
      app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
  }
  public class DefaultDependencyResolver : System.Web.Mvc.IDependencyResolver, System.Web.Http.Dependencies.IDependencyResolver
  {
    protected IServiceProvider serviceProvider;

    public DefaultDependencyResolver(IServiceProvider serviceProvider)
    {
      this.serviceProvider = serviceProvider;
    }

    public IDependencyScope BeginScope()
    {
      return new DefaultDependencyResolver(this.serviceProvider.CreateScope().ServiceProvider);
    }

    public void Dispose()
    {
    }

    public object GetService(Type serviceType)
    {
      return this.serviceProvider.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
      return this.serviceProvider.GetServices(serviceType);
    }
  }

  public static class ServiceProviderExtensions
  {
    public static IServiceCollection AddControllersAsServices(this IServiceCollection services,
        IEnumerable<Type> controllerTypes)
    {
      foreach (var type in controllerTypes)
      {
        services.AddTransient(type);
      }

      return services;
    }
  }
}

我只更改了我的一個簡單控制器以注入適當的 BL 接口並通過前端進行測試,但它得到一個“確保控制器具有無參數的公共構造函數”

所以除了啟動和控制器之外,我什么都沒碰過。

問題:

1:任何人都可以看到我所做的事情是否缺少任何東西?

2:我可以通過調試看到,我擁有的控制器正在通過 ConfigureServices() 填充服務。 我需要做任何額外的事情來將它們與它們的依賴項聯系起來嗎?

[UPDATE 1 of 2]:控制器:基本上只是改變了構造函數,所以它有一個參數。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using TA.Services.BL.BusinessLogic;
using TA.Services.BL.Interface;
using TA.Services.DTO.DTO;
using TA.Services.WebAPI.Providers;

using Syncfusion.EJ2.Base;
using Newtonsoft.Json;
using TA.Services.WebAPI.Helpers;

namespace TA.Services.WebAPI.Controllers
{
  [WebApiConfig.CamelCaseControllerConfig]

  public class AuditsController : ApiController
  {
    private readonly IAuditsBL _auditsBL;
    
    /*
    public AuditsController()
    {
      _auditsBL = new AuditsBL();
    }
    */
    public AuditsController(IAuditsBL auditsBL)
    {
      _auditsBL = auditsBL;
    }
    ...
  }
}

[更新 2 的 2]:

對 ConfigureServices 進行了更改,將單例添加到服務中

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
      .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
      .Where(t => typeof(IController).IsAssignableFrom(t)
                  || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
  //Added this
  services.AddSingleton<IAuditsBL, AuditsBL>();
}

當我運行應用程序時,我得到的服務填充如下: 在此處輸入圖像描述

當我運行前端並導航到調用 AuditController 的位置時,我在 devtools 中得到以下信息: 在此處輸入圖像描述

  1. 將 MVC 解析器設置為您的Configuration方法。 我不知道為什么在 web api 控制器中需要它。
DependencyResolver.SetResolver(resolver);
  1. 設置解析器后配置路由:
config.Routes.MapHttpRoute(
       name: "MyDefaultApi",
       routeTemplate: "api/{controller}/{id}",
       defaults: new { id = RouteParameter.Optional }
);
  1. ConfigureServices將單例添加到服務中(您已經添加了這個)
services.AddSingleton<IAuditsBL, AuditsBL>();

最后配置方法如下:

public void Configuration(IAppBuilder app)
        {
            var services = new ServiceCollection();
            ConfigureServices(services);
            var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());
            // Set MVC Resolver
            DependencyResolver.SetResolver(resolver);

            // MVC Route
            RouteTable.Routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

            // Set WebAPI Resolver and register
            HttpConfiguration config = new HttpConfiguration();
            config.DependencyResolver = resolver;

            // WebApi Route
            config.Routes.MapHttpRoute(
                name: "MyDefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
           );

            app.UseWebApi(config);
        }
 public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
              .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
              .Where(t => typeof(IController).IsAssignableFrom(t)
                          || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
            services.AddSingleton<IMyInterface, MyClass>();
        }

git:鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM