asp.net – Autofac懒惰属性注入

我正在尝试将业务逻辑实现注入Web API基础控制器.基本控制器中的某些属性始终为null.

另外我怎么做懒人注射?

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; }
}

解决方法

默认情况下,DI框架不会解析控制器.您需要添加AddControllerAsServices才能通过您选择的DI解析它们.

this GitHub issue开始:

Hi,

Maybe I’m wrong but as I tested deeply (and checked Mvc source code),Controllers are not resolved from IServiceProvider,but only constructor arguments of them are resolved from IServiceProvider.

Is that by design? I’m very suprised. Because,I’m using a different DI framework which supports property injection. And I can not use property injection since Controller instances are not requested from IServiceProvider.


您是否在Startup中添加了AddControllersAsServices(https://github.com/aspnet/Mvc/blob/ab76f743f4ee537939b69bdb9f79bfca35398545/test/WebSites/ControllersFromServicesWebSite/Startup.cs#L37)

以上示例引用以供将来参考.

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容器进行延迟实例化.最适合您的是创建工厂类并注入工厂而不是具体服务.

但通常你不需要懒惰的实例化,服务的实例化应该很快.如果不是,你可能在构造函数中做一些时髦的东西(连接某个地方,或做其他长时间运行的操作),这是一种反模式.

相关文章

引言 本文从Linux小白的视角, 在CentOS 7.x服务器上搭建一个...
引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要...
一. 宏观概念 ASP.NET Core Middleware是在应用程序处理管道...
背景 在.Net和C#中运行异步代码相当简单,因为我们有时候需要...
HTTP基本认证 在HTTP中,HTTP基本认证(Basic Authenticatio...
1.Linq 执行多列排序 OrderBy的意义是按照指定顺序排序,连续...