大威天龙赵文卓 發表於 2025-6-28 11:02:56

Asp.Net 动态接口中属性注入未生效的问题解决

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">- 不加AddControllersAsServices()</a></li><li><a href="#_label1">- 加AddControllersAsServices()</a></li></ul></div><p>我有一个授权Service【AuthService】继承抽象类【ApplicationService】,程序会后会将所有继承IApplicationService的Service动态转换为Api接口,在swagger使用原生Controller控制器接口调用AuthService是没有问题的,测试【AuthService】的动态接口报错【LazyServiceProvider为null】</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202506/2025062810574684.png" /></p>
<p>容器注入选择的是:<strong>Autofac,所有服务均注册</strong></p>
<p>抽象类代码如下:</p>
<p>其中LazyServiceProvider是通过属性注入来实现的</p>
<div class="jb51code"><pre class="brush:csharp;">   
    public abstract class ApplicationService : IApplicationService, IDynamicApi
    {
      /// &lt;summary&gt;
      /// 懒加载服务驱动(属性注入)
      /// &lt;/summary&gt;
      
      public ILazyServiceProvider LazyServiceProvider { get; set; }
      #region Private-Attribute
      private IMapper _ObjectMapper;
      private ICurrentUserService _CurrentUser;
      private IPermissionChecker _IPermissionChecker;
      #endregion Private-Attribute
      #region Protected-Attribute
      /// &lt;summary&gt;
      /// AutoMap
      /// &lt;/summary&gt;
      protected IMapper ObjectMapper
      {
            get
            {
                if (_ObjectMapper == null)
                {
                  _ObjectMapper = LazyServiceProvider.LazyGetRequiredService&lt;IMapper&gt;();
                }
                return _ObjectMapper;
            }
      }
      /// &lt;summary&gt;
      /// 当前用户
      /// &lt;/summary&gt;
      protected ICurrentUserService CurrentUser
      {
            get
            {
                if (_CurrentUser == null)
                {
                  _CurrentUser = LazyServiceProvider.LazyGetRequiredService&lt;ICurrentUserService&gt;();
                }
                return _CurrentUser;
            }
      }
      /// &lt;summary&gt;
      /// 权限检查
      /// &lt;/summary&gt;
      protected IPermissionChecker PermissionChecker
      {
            get
            {
                if (_IPermissionChecker == null)
                {
                  _IPermissionChecker = LazyServiceProvider.LazyGetRequiredService&lt;IPermissionChecker&gt;();
                }
                return _IPermissionChecker;
            }
      }
      #endregion Protected-Attribute
    }</pre></div>
<p>解决方法:</p>
<p>在ASP.NET Core配置中:</p>
<div class="jb51code"><pre class="brush:csharp;">builder.Services.AddControllers()
    .AddControllersAsServices(); // 这很重要,确保控制器由DI容器解析</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202506/2025062810574612.png" /></p>
<p><code>AddControllersAsServices()</code>的主要作用是:</p>
<ol><li><p><strong>将控制器注册为服务</strong>:将所有控制器类注册到依赖注入(DI)容器中</p></li><li><p><strong>使用DI容器解析控制器</strong>:确保控制器实例由DI容器创建,而不是由MVC框架直接实例化</p></li></ol>
<p><span><strong>加与不加的区别:</strong></span></p>
<p class="maodian"><a name="_label0"></a></p><h2>- 不加AddControllersAsServices()</h2>
<ol><li><p><strong>控制器创建方式</strong>:</p>
<ul><li><p>MVC框架会直接使用&nbsp;<code>ActivatorUtilities.CreateInstance</code>&nbsp;创建控制器实例</p></li><li><p>只支持构造函数注入,不支持属性注入</p></li></ul></li><li><p><strong>生命周期</strong>:</p>
<ul><li><p>每个请求都会创建新的控制器实例</p></li><li><p>生命周期完全由MVC框架管理</p></li></ul></li><li><p><strong>限制</strong>:</p>
<ul><li><p>无法使用Autofac等第三方容器的高级功能(如属性注入)</p></li><li><p>无法自定义控制器的解析过程</p></li></ul></li></ol>
<p class="maodian"><a name="_label1"></a></p><h2>- 加AddControllersAsServices()</h2>
<ol><li><p><strong>控制器创建方式</strong>:</p>
<ul><li><p>控制器实例由DI容器创建</p></li><li><p>支持完整的DI功能,包括构造函数注入和属性注入</p></li></ul></li><li><p><strong>优势</strong>:</p>
<ul><li><p>可以使用第三方容器(如Autofac)的所有功能</p></li><li><p>支持属性注入</p></li><li><p>可以自定义控制器的生命周期</p></li><li><p>可以在控制器解析前后执行自定义逻辑</p></li></ul></li><li><p><strong>生命周期</strong>:</p>
<ul><li><p>默认仍然是每个请求创建新实例(Transient)</p></li><li><p>但可以通过注册时指定来改变生命周期</p></li></ul></li></ol>
頁: [1]
查看完整版本: Asp.Net 动态接口中属性注入未生效的问题解决