ASP.NET Core Autofac 惰性属性注入为null 动态注入

2021-04-03  乐帮网

netcore autofac

仅仅做为ASP.NET Core 3.0 的Autofac注入参考,摘自网文,但是对学习研究auto注入帮助很大。内容如下:
我正在尝试业务逻辑注入到Web API基础控制器中。不知何故,基本控制器中的屬性始終为null。Autofac惰性属性注入
另外我应该如何做懶惰注射?

Startups.cs

public IServiceProvider ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 
    services.AddMvc(); 

    var containerBuilder = new ContainerBuilder(); 
    containerBuilder.RegisterType<ViewBusinessLogic>().As<IViewBusinessLogic>(). 
     PropertiesAutowired(); 
    containerBuilder.Populate(services); 

    var container = containerBuilder.Build(); 

    return container.Resolve<IServiceProvider>(); 
} 

接口,实现和基本控制器:

public interface IViewBusinessLogic 
{ 
    IEnumerable<dynamic> GetView(Guid viewId); 
} 

public class ViewBusinessLogic : BusinessLogic, IViewBusinessLogic 
{ 
    public IEnumerable<dynamic> GetView(Guid viewId) 
    { 
     return new List<dynamic> 
     { 
      new { Test = "Test1" }, 
      new { Test = "Test2" } 
     }; 
    } 
} 

public abstract class BaseController : Controller 
{ 
    public IViewBusinessLogic ViewBusinessLogic { get; } 
} 

这不是一个Autofac问题,它是一个ASP.NET Core的问题。如果沒有'AddControllersAsServices',任何其他DI提供程序都无法法使用属性注入 。
控制器不是默认由DI框架解決。您需要添加AddControllerAsServices以使其由您选择的DI解決。
参考this GitHub issue: https://github.com/aspnet/Mvc/issues/4855#issuecomment-225364069
里面有这么一段内容很重要:
我经常仔细测试(和查阅的mvc源代),发现控制器不从IServiceProvider提供实现生成,但只有构造函数的参数从IServiceProvider中生成。就是这么设计的?我也很惊讶。因为我正在使用支持属性注入的不同DI框架。而且我不能使用屬性注入,因为Controller实例不是从IServiceProvider中生成的。

详细内容也可以 参考这里:https://github.com/aspnet/Mvc/blob/ab76f743f4ee537939b69bdb9f79bfca35398545/test/WebSites/ControllersFromServicesWebSite/Startup.cs#L37

上面的例子引述以供将来参考添加AddControllersAsServices。

public void ConfigureServices(IServiceCollection services) 
{ 
    var builder = services 
     .AddMvc() 
     .ConfigureApplicationPartManager(manager => manager.ApplicationParts.Clear()) 
     .AddApplicationPart(typeof(TimeScheduleController).GetTypeInfo().Assembly) 
     .ConfigureApplicationPartManager(manager => 
     { 
      manager.ApplicationParts.Add(new TypesPart(
       typeof(AnotherController), 
       typeof(ComponentFromServicesViewComponent), 
       typeof(InServicesTagHelper))); 

      manager.FeatureProviders.Add(new AssemblyMetadataReferenceFeatureProvider()); 
     }) 

     // This here is important 
     .AddControllersAsServices() 
     .AddViewComponentsAsServices() 
     .AddTagHelpersAsServices(); 

    services.AddTransient<QueryValueService>(); 
    services.AddTransient<ValueService>(); 
    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 
} 

对于你问题的第二部分:我不认为这是可能通过IoC容器有延时实例化的场景。最适合你的是创建一个工厂类并注入工厂而不是具体的服务。
但是通常你不需要惰性实例化,服务的实例化应该是快速的。如果不是的话,你可能在构造函数中做了一些耗时的事情,一般不推荐这么 做。

原文:http://hk.uwenku.com/question/p-vrkpfqdo-bgk.html

公众号二维码

关注我的微信公众号
在公众号里留言交流
投稿邮箱:1052839972@qq.com

庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。

欧阳修

付款二维码

如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力