Asp.net web api Autofac.Core.DependencyResolutionException将config.DependencyResolver.GetService(typeof(IUserService))作为IUserService执行

Asp.net web api Autofac.Core.DependencyResolutionException将config.DependencyResolver.GetService(typeof(IUserService))作为IUserService执行,asp.net-web-api,autofac,Asp.net Web Api,Autofac,我需要在身份验证处理程序中获取类型为IUserService的注册实例 // Register services // Build the container. var containr = builder.Build(); var resolver = new AutofacWebApiDependencyResolver(container); configuration.DependencyResolver = resolver; 现在运行这行代码时: var userServi

我需要在身份验证处理程序中获取类型为IUserService的注册实例

// Register services

// Build the container.
 var containr = builder.Build();
 var resolver = new AutofacWebApiDependencyResolver(container);
 configuration.DependencyResolver = resolver;
现在运行这行代码时:

var userService = configuration.DependencyResolver.GetService(typeof (IUserService)) as IUserService;
我得到一个例外:

   An exception of type 'Autofac.Core.DependencyResolutionException' occurred in Autofac.dll but was not handled in user code

    Additional information: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
我不想手动创建userservice,因为这样我还必须手动解析依赖的类

当我不在请求中时,如何获得特定服务?依赖项。解析程序未知/无法解析为以某种方式使用它

更新

public static void Register(HttpSelfHostConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            var resolver = (AutofacWebApiDependencyResolver)config.DependencyResolver;

            var scope = resolver.GetRootLifetimeScope();
            var userService = scope.Resolve<IUserService>();
            scope.Dispose();

            var authenticationHandler = new AuthenticationHandler(userService);
            var tokenHandler = new TokenHandler();

            config.MessageHandlers.Add(new HttpsHandler());
            config.MessageHandlers.Add(new AllowCommonVerbsHandler());
            config.MessageHandlers.Add(authenticationHandler);
            config.MessageHandlers.Add(tokenHandler);

            config.Routes.MapHttpRoute(
                name: "Authentication",
                routeTemplate: "api/users/{id}",
                defaults: new { controller = "users", id = RouteParameter.Optional },
                constraints: null,
                handler: authenticationHandler // Put this handler later on the DefaultApi
            );
            config.Routes.MapHttpRoute(
               name: "TokenApi",
               routeTemplate: "api/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional },
               constraints: null,
               handler: tokenHandler
               );
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { controller = "Home", action = "Start" }
                );

            var jsonFormatter = new JsonMediaTypeFormatter();
            config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
        }
我现在已将服务注册更改为:

  builder.RegisterType<UserService>()
                   .As<IUserService>()
                   .WithParameter(namedParameter)
                   .InstancePerLifetimeScope();
builder.RegisterType()
.As()
.WithParameter(名称参数表)
.InstancePerLifetimeScope();
而不是InstancePerRequestApi()

并将用户服务解析为:

var resolver = (AutofacWebApiDependencyResolver)config.DependencyResolver;

            var bla = resolver.GetRootLifetimeScope();
            IUserService userService = bla.Resolve<IUserService>(); // Woot!
var resolver=(AutofacWebApiDependencyResolver)config.DependencyResolver;
var bla=resolver.GetRootLifetimeScope();
IUserService userService=bla.Resolve();//呜!
这很有效,但我以前的InstancePerApiRequest呢?我也想保留它

更新

public static void Register(HttpSelfHostConfiguration config)
        {
            config.MapHttpAttributeRoutes();

            var resolver = (AutofacWebApiDependencyResolver)config.DependencyResolver;

            var scope = resolver.GetRootLifetimeScope();
            var userService = scope.Resolve<IUserService>();
            scope.Dispose();

            var authenticationHandler = new AuthenticationHandler(userService);
            var tokenHandler = new TokenHandler();

            config.MessageHandlers.Add(new HttpsHandler());
            config.MessageHandlers.Add(new AllowCommonVerbsHandler());
            config.MessageHandlers.Add(authenticationHandler);
            config.MessageHandlers.Add(tokenHandler);

            config.Routes.MapHttpRoute(
                name: "Authentication",
                routeTemplate: "api/users/{id}",
                defaults: new { controller = "users", id = RouteParameter.Optional },
                constraints: null,
                handler: authenticationHandler // Put this handler later on the DefaultApi
            );
            config.Routes.MapHttpRoute(
               name: "TokenApi",
               routeTemplate: "api/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional },
               constraints: null,
               handler: tokenHandler
               );
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { controller = "Home", action = "Start" }
                );

            var jsonFormatter = new JsonMediaTypeFormatter();
            config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
        }
公共静态无效寄存器(HttpSelfHostConfiguration配置)
{
config.maphttpAttribute路由();
var resolver=(AutofacWebApiDependencyResolver)config.DependencyResolver;
var scope=resolver.GetRootLifetimeScope();
var userService=scope.Resolve();
scope.Dispose();
var authenticationHandler=新的authenticationHandler(userService);
var tokenHandler=new tokenHandler();
Add(新的HttpsHandler());
Add(新的AllowCommonVerbsHandler());
config.MessageHandlers.Add(authenticationHandler);
config.MessageHandlers.Add(tokenHandler);
config.Routes.MapHttpRoute(
名称:“身份验证”,
routeTemplate:“api/users/{id}”,
默认值:new{controller=“users”,id=RouteParameter.Optional},
约束:null,
handler:authenticationHandler//稍后将此处理程序放在DefaultApi上
);
config.Routes.MapHttpRoute(
名称:“TokenApi”,
routeTemplate:“api/{controller}/{id}”,
默认值:new{id=RouteParameter.Optional},
约束:null,
处理程序:令牌处理程序
);
config.Routes.MapHttpRoute(
名称:“DefaultApi”,
routeTemplate:“api/{controller}/{id}”,
默认值:新建{controller=“Home”,action=“Start”}
);
var jsonFormatter=新的JsonMediaTypeFormatter();
Replace(typeof(IContentNegotiator),newjsonContentnegotiator(jsonFormatter));
}

我假设您的身份验证处理程序是一个DelegatingHandler。如果是这种情况,您可以使用以下代码访问当前请求的生存期范围:

var scope = request.GetDependencyScope();
var requestScope = scope.GetRequestLifetimeScope();
在上面的代码中,
request
HttpRequestMessage
实例传递给
DelegatingHandler
sendsync
方法

在这种情况下,您将无法拥有构造函数依赖项。在
SendAsync
方法中,当需要使用
IUserService
实例时,使用上面提供的代码解析它

要为处理程序创建测试,您需要模拟WebAPI依赖范围

var builder = new ContainerBuilder();
// Configure container for test.
var container = builder.Build();
var request = new HttpRequestMessage();
var lifetimeScope = container.BeginLifetimeScope(AutofacWebApiDependencyResolver.ApiRequestTag);
var scope = new AutofacWebApiDependencyScope(lifetimeScope);
request.Properties.Add(HttpPropertyKeys.DependencyScope, scope);
有关如何对
DelegatingHandler
进行单元测试,请参阅
HttpMessageInvoker


我认为您可能忘记了在使用
IRepository
创建类对象时添加readonly,或者在声明构造函数之前忘记了访问修饰符。希望这能对您有所帮助。

你好,Alex,我不是委托处理程序的成员。我在static routes.Register方法中,在该方法中我创建了一个authenticationhandler,它需要构造函数中的IUserService。查看我的更新。确定现在Every解决方案的崩溃:1)我已将IUserService注册为InstancePeraPireRequest,然后在WebApiRoutesConfig中崩溃,如下行:var scope=resolver.GetRootLifetimeScope();var userService=scope.Resolve();或者2)我已将IUserService注册为InstancePerLifetimeScope,然后在即将创建控制器时,它在集成测试中崩溃:“无法解析实例,无法从此LifetimeScope创建嵌套的生存期,因为它已被释放。”我更新了我的答案,注意到在这种情况下,构造函数注入是不可能的。这是Web API本身施加的限制。我已经重构了业务逻辑,现在似乎不需要webApiConfig文件中的userService实例:-)以防有人遇到同样的问题。。。需要包括以下名称空间:使用Autofac;使用Autofac.Integration.WebApi;