Suncx / NAutowired

ASP.NET CORE Field Injection Implement

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NAutowired

NuGet

ASP.NET CORE 通过属性注入依赖

为什么要使用

ASP.NET CORE自带的DI框架,需要通过构造函数进行注入,例如

  [Route("api/[controller]")]
  [ApiController]
  public class FooController : ControllerBase {

    private readonly FooService fooService;

    //构造函数注入方式
    public FooController(FooService fooService) {
      this.fooService = fooService;
    }

    [HttpGet]
    public ActionResult<string> Get() {
      return fooService == null ? "failure" : "success";
    }
  }

这种方式当项目越来越大的情况下, 一个Service类中可能需要注入数十个依赖, 这时构造函数就显得极为臃肿. NAutowired实现了Field Injection, 能直接通过类的属性进行注入.

如何使用

  • 查看使用样例
  • nuget包管理器中引入NAutowiredNAutowired.Core
  • NAutowired包应该只在Web项目中被引用, NAutowired.Core包则在需要添加特性的项目中被引用.
  • Startup.cs中替换默认的IControllerActivator实现为NAutowiredControllerActivator.
  public class Startup {
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services) {
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
      //替换默认的`IControllerActivator`实现.
      services.AddSingleton<IControllerActivator, NAutowiredControllerActivator>();
    }
  }
  • 使用Autowired
  public class Startup {
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services) {
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
      //将FooService加到容器
      services.AddScoped<FooService>();
    }
  }
  [Route("api/[controller]")]
  [ApiController]
  public class FooController : ControllerBase {

    //使用Autowired Attribute注入实例
    [Autowired]
    private FooService FooService { get; set; }

    [HttpGet]
    public ActionResult<string> Get() {
      return FooService == null ? "failure" : "success";
    }
  }
  • Filter中使用NAutowired
  public class Startup {
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services) {
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
      //将Filter加到容器
      services.AddScoped<AuthorizationFilter>();
    }
  }
  //使用 ServiceFilterAttribute
  [NAutowired.Attributes.ServiceFilter(typeof(AuthorizationFilter))]
  public class FooController : ControllerBase {

  }
  public class AuthorizationFilter : IAuthorizationFilter {
    [Autowired]
    private FooService FooService { get; set; }

    public void OnAuthorization(AuthorizationFilterContext context) {
      System.Console.WriteLine($"{FooService.ToString()} in filter");
      return;
    }
  }

NAutowired使用ASP.NET CORE自带的DI容器获取实例, 它解决的仅仅是注入依赖的方式, 因此您依旧可以使用services.AddScope<FooService>()方式将FooService加入到容器.

进阶

  • 您可以通过[Autowired(Type)]方式注入特定的类型.
  [Route("api/[controller]")]
  [ApiController]
  public class FooController : ControllerBase {

    //注入特定的实例
    [Autowired(typeof(FooService))]
    private IFooService FooService { get; set; }

    [HttpGet]
    public ActionResult<string> Get() {
      return FooService == null ? "failure" : "success";
    }
  }
  • NAutowired提供了AddAutoDependencyInjection(assemblyName)方法进行自动容器注入.这种方式让您无需在Startup.cs中一个个的将类型加入到容器.
  public class Startup {
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services) {
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
      //services.AddScoped<FooService>();
      //使用自动注入
      services.AddAutoDependencyInjection("NAutowiredSample");
    }
  }

使用[Service] [Repository] [Component] [ServiceFilter]特性标记类

  //默认DependencyInjectionModeEnum值为Scoped
  [Service]
  //DependencyInjectionModeEnum可供选择依赖注入的生命周期
  //[Service(DependencyInjectionModeEnum.Singleton)]
  public class FooService {
  }

NAutowired会自动扫描AddAutoDependencyInjection(assemblyName)方法配置的程序集下的所有类, 并将具有[Service] [Repository] [Component] [ServiceFilter]特性的类注入到容器.

说明

  • 由于NAutowired并没有替换ASP.NET CORE默认的DI方式, 所以您依然可以通过构造函数注入依赖, NAutowiredASP.NET CORE默认的DI方式完全兼容.
  • 使用Field Injection是一个反模式的东西, 它违反了显式依赖原则.

About

ASP.NET CORE Field Injection Implement

License:MIT License


Languages

Language:C# 98.2%Language:Batchfile 1.8%