Autofac懒惰属性注入

时间:2016-09-18 10:01:43

标签: asp.net dependency-injection asp.net-core 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; }
}

1 个答案:

答案 0 :(得分:2)

默认情况下,DI框架无法解析控制器。您需要添加AddControllerAsServices才能通过您选择的DI解决这些问题。

来自this GitHub issue

  
    

您好,

         

也许我错了但是当我深入测试(并检查了Mvc源代码)时,控制器无法从IServiceProvider解析,但只有IServiceProvider解析了它们的构造函数参数。 / p>          

这是设计吗?我非常惊讶。因为,我使用了支持属性注入的不同DI框架。而且我不能使用属性注入,因为IServiceProvider没有请求Controller实例。

  
     

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

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