C# Autofac';s上下文绑定在ASP.Core 2.0中不起作用

C# Autofac';s上下文绑定在ASP.Core 2.0中不起作用,c#,asp.net-core-mvc,autofac,asp.net-core-2.0,asp.net-core-webapi,C#,Asp.net Core Mvc,Autofac,Asp.net Core 2.0,Asp.net Core Webapi,最近,我不得不利用Autofac支持的上下文绑定,但在ASP.NET Core 2.0中,它不起作用。我遵循FAQ页面上的示例(选项2和3),但是我设法使其仅在ASP.NET MVC 5和ASP.NET WEB API 2项目中工作。 例如: 以下绑定配置无法运行: var builder = new ContainerBuilder(); builder.RegisterType<PostalServiceSender>() .As<ISender>()

最近,我不得不利用Autofac支持的上下文绑定,但在ASP.NET Core 2.0中,它不起作用。我遵循FAQ页面上的示例(选项2和3),但是我设法使其仅在ASP.NET MVC 5和ASP.NET WEB API 2项目中工作。 例如:

以下绑定配置无法运行:

var builder = new ContainerBuilder();

builder.RegisterType<PostalServiceSender>()
       .As<ISender>()
       .AsSelf();
builder.RegisterType<EmailNotifier>()
       .As<ISender>()
       .AsSelf()
       .InstancePerLifetimeScope();

builder.RegisterType<DefaultSender>()
           .As<ISender>()
           .InstancePerLifetimeScope();

builder.RegisterType<ShippingController>()
       .WithParameter(
         new ResolvedParameter(
           (pi, ctx) => pi.ParameterType == typeof(ISender),
           (pi, ctx) => ctx.Resolve<PostalServiceSender>()))
           .InstancePerLifetimeScope();
builder.RegisterType<CustomersController>();
       .WithParameter(
         new ResolvedParameter(
           (pi, ctx) => pi.ParameterType == typeof(ISender),
           (pi, ctx) => ctx.Resolve<EmailNotifier>()))
           .InstancePerLifetimeScope();
var container = builder.Build();
var builder=newcontainerbuilder();
builder.RegisterType()
.As()
.AsSelf();
builder.RegisterType()
.As()
.AsSelf()
.InstancePerLifetimeScope();
builder.RegisterType()
.As()
.InstancePerLifetimeScope();
builder.RegisterType()
.带参数(
新解析参数(
(pi,ctx)=>pi.ParameterType==typeof(ISender),
(pi,ctx)=>ctx.Resolve())
.InstancePerLifetimeScope();
RegisterType();
.带参数(
新解析参数(
(pi,ctx)=>pi.ParameterType==typeof(ISender),
(pi,ctx)=>ctx.Resolve())
.InstancePerLifetimeScope();
var container=builder.Build();
从上述绑定配置中可以预期DefaultSender类是ISender的默认实现。只有PostalServiceSenderCustomerNotifier配置为接收不同的ISender实现。 不幸的是,DefaultSender实现是在任何请求ISender的地方传递的。
有人在.NET Core 2.0中经历过这种行为吗?

您的配置非常好,除了ASP.NET Core controller,一切都应该正常工作

ASP.net core中的控制器不是由
Autofac
创建的,而是由B ASP.net core创建的:

默认情况下,ASP.NET Core将从容器解析控制器参数,但实际上不会从容器解析控制器。这通常不是问题,但它确实意味着:
  • 控制器的生命周期由框架处理,而不是请求生命周期。
  • 控制器构造函数参数的生命周期由请求生命周期处理。
  • 在控制器注册期间可能进行的特殊接线(如设置属性注入)将无法工作。

    在向服务集合注册MVC时,可以通过指定
    addControllerAsservices()
    来更改此设置。这样做将在调用
    builder.Populate(services)
    时自动将控制器类型注册到
    IServiceCollection


    >>

    您只需调用
    AddControllersAsServices

    // Add controllers as services so they'll be resolved.
    services.AddMvc().AddControllersAsServices();
    
    顺便说一句,即使您的代码有效,多次注册同一服务并依赖默认顺序也不是最佳做法

    builder.RegisterType<PostalServiceSender>()
           .Keyed<ISender>("postal");
    builder.RegisterType<EmailNotifier>()
           .Keyed<ISender>("email")
           .InstancePerLifetimeScope();
    builder.RegisterType<DefaultSender>()
           .As<ISender>()
           .InstancePerLifetimeScope();       
    
    builder.RegisterType()
    .Keyed(“邮政”);
    builder.RegisterType()
    .Keyed(“电子邮件”)
    .InstancePerLifetimeScope();
    builder.RegisterType()
    .As()
    .InstancePerLifetimeScope();
    
    您的控制器如下所示:

    builder.RegisterType<ShippingController>()
           .WithParameter(
             new ResolvedParameter(
               (pi, ctx) => pi.ParameterType == typeof(ISender),
               (pi, ctx) => ctx.ResolveNamed<ISender>("postal")))
           .InstancePerLifetimeScope();
    builder.RegisterType<CustomersController>()
           .WithParameter(
             new ResolvedParameter(
               (pi, ctx) => pi.ParameterType == typeof(ISender),
               (pi, ctx) => ctx.ResolveNamed<ISender>("email")))
           .InstancePerLifetimeScope();
    
    builder.RegisterType()
    .带参数(
    新解析参数(
    (pi,ctx)=>pi.ParameterType==typeof(ISender),
    (pi,ctx)=>ctx.resolveName(“邮政”))
    .InstancePerLifetimeScope();
    builder.RegisterType()
    .带参数(
    新解析参数(
    (pi,ctx)=>pi.ParameterType==typeof(ISender),
    (pi,ctx)=>ctx.resolveName(“电子邮件”))
    .InstancePerLifetimeScope();
    
    您的配置非常好,除了ASP.net core controller之外,一切都应该正常工作

    ASP.net core中的控制器不是由
    Autofac
    创建的,而是由B ASP.net core创建的:

    默认情况下,ASP.NET Core将从容器解析控制器参数,但实际上不会从容器解析控制器。这通常不是问题,但它确实意味着:
  • 控制器的生命周期由框架处理,而不是请求生命周期。
  • 控制器构造函数参数的生命周期由请求生命周期处理。
  • 在控制器注册期间可能进行的特殊接线(如设置属性注入)将无法工作。

    在向服务集合注册MVC时,可以通过指定
    addControllerAsservices()
    来更改此设置。这样做将在调用
    builder.Populate(services)
    时自动将控制器类型注册到
    IServiceCollection


    >>

    您只需调用
    AddControllersAsServices

    // Add controllers as services so they'll be resolved.
    services.AddMvc().AddControllersAsServices();
    
    顺便说一句,即使您的代码有效,多次注册同一服务并依赖默认顺序也不是最佳做法

    builder.RegisterType<PostalServiceSender>()
           .Keyed<ISender>("postal");
    builder.RegisterType<EmailNotifier>()
           .Keyed<ISender>("email")
           .InstancePerLifetimeScope();
    builder.RegisterType<DefaultSender>()
           .As<ISender>()
           .InstancePerLifetimeScope();       
    
    builder.RegisterType()
    .Keyed(“邮政”);
    builder.RegisterType()
    .Keyed(“电子邮件”)
    .InstancePerLifetimeScope();
    builder.RegisterType()
    .As()
    .InstancePerLifetimeScope();
    
    您的控制器如下所示:

    builder.RegisterType<ShippingController>()
           .WithParameter(
             new ResolvedParameter(
               (pi, ctx) => pi.ParameterType == typeof(ISender),
               (pi, ctx) => ctx.ResolveNamed<ISender>("postal")))
           .InstancePerLifetimeScope();
    builder.RegisterType<CustomersController>()
           .WithParameter(
             new ResolvedParameter(
               (pi, ctx) => pi.ParameterType == typeof(ISender),
               (pi, ctx) => ctx.ResolveNamed<ISender>("email")))
           .InstancePerLifetimeScope();
    
    builder.RegisterType()
    .带参数(
    新解析参数(
    (pi,ctx)=>pi.ParameterType==typeof(ISender),
    (pi,ctx)=>ctx.resolveName(“邮政”))
    .InstancePerLifetimeScope();
    builder.RegisterType()
    .带参数(
    新解析参数(
    (pi,ctx)=>pi.ParameterType==typeof(ISender),
    (pi,ctx)=>ctx.resolveName(“电子邮件”))
    .InstancePerLifetimeScope();
    
    您的意思是
    ShippingController
    接收的是
    DefaultSender
    ,而不是预期的
    postalservicessender
    ?你能分享这个控制器的构造器吗。这也可能与此相关:您的意思是
    ShippingController
    接收的是
    DefaultSender
    ,而不是预期的
    postalservicessender
    ?你能分享一下吗