在.NET Core MVC项目中使用Autofac属性注入

4

我有一个控制器,其中包含一个类型为ILol的属性和实现了ILol接口的Lol类。

public class UniversityController : Controller
{
    public ILol Lol { get; set; }

    public IActionResult Index()
    {
        ViewData["Header"] = "Hello, world!";
        ViewData["NullCheck"] = Lol == null ? "It's null" : Lol.GetLol();

        return View();
    }
}

我尝试以以下方式(在我的 Startup 类的一部分)使用Autofac进行属性注入

public IContainer ApplicationContainer { get; private set; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        // Dependency resolving.
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        ContainerBuilder builder = new ContainerBuilder();

        builder.RegisterType<Lol>().As<ILol>().PropertiesAutowired().InstancePerLifetimeScope();
        builder.Populate(services);

        IContainer container = builder.Build();

        ApplicationContainer = container;

        return new AutofacServiceProvider(container);
    }

它不起作用。在运行时属性为空。尽管构造函数注入正常工作。

1个回答

0

您需要指定在哪些控制器中需要使用属性注入:

 var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
            .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
 builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();

并调用AddControllersAsServices():

services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddControllersAsServices();

如果您需要注册属性注入,请在构建器中注册更多类型PropertiesAutowired()。

而ConfigureServices看起来会像这样:

public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        // Dependency resolving.
        services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
        .AddControllersAsServices();

        ContainerBuilder builder = new ContainerBuilder();
        builder.Populate(services);//Autofac.Extensions.DependencyInjection

        builder.RegisterType<Lol>().As<ILol>().PropertiesAutowired().InstancePerLifetimeScope();
        builder.Populate(services);

        var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
            .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
        builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();

        IContainer container = builder.Build();

        ApplicationContainer = container;

        return new AutofacServiceProvider(container);
    }

在 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1) 上调用 AddControllersAsServices(),请参考我的示例 https://github.com/svoychik/DotNetCore.AutofacExample。 - svoychik
您还需要确保在使用RegisterAssemblyTypes注册控制器之前调用builder.Populate(services)。当您使用AddControllersAsServices时,服务将添加到IServiceCollection中,并调用Populate将其转换为Autofac注册。默认情况下,Autofac将使用最后添加的注册作为默认值,并且您希望该注册具有PropertiesAutowired - Alex Meyer-Gleaves

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接