本文介绍了Autofac懒惰属性注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将业务逻辑实现注入Web API基本控制器.基本控制器中的属性总是null.

I'm trying to inject business logic implementations into web API base controller. Somehow property in base controller is always 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解决.

Controllers aren't resolved by the DI framework by default. You need to add AddControllerAsServices to have them be resolved by the DI of your choice.

来自此GitHub问题:

也许我错了,但是当我进行深入测试(并检查Mvc源代码)时,不是从IServiceProvider解析控制器,而是仅从IServiceProvider解析了它们的构造函数参数.

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.

这是设计使然吗?我很惊讶因为,我使用了另一个支持属性注入的DI框架.而且我不能使用属性注入,因为没有从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.

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

Have you added AddControllersAsServices in your Startup (https://github.com/aspnet/Mvc/blob/ab76f743f4ee537939b69bdb9f79bfca35398545/test/WebSites/ControllersFromServicesWebSite/Startup.cs#L37)

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

The example above quoted for future reference.

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

As for the second part of your question: I don't think it's possible to have lazy instantiation via IoC container at all. Best fit for you is to create a factory class and inject the factory rather than the concrete service.

但是通常无论如何您都不需要惰性实例化,服务的实例化应该是快速的.如果不是这样,您可能会在构造函数中做一些时髦的事情(连接某个地方或执行其他长时间运行的操作),这是一种反模式.

But usually you don't need lazy instantiation anyways, the instantiation of services should be fast. If it's not, you probably doing some funky stuff in the constructor (connecting somewhere, or doing other long running operations), which is an anti-pattern.

这篇关于Autofac懒惰属性注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 21:42
查看更多