Asp.net web api Autofac.Core.DependencyResolutionException将config.DependencyResolver.GetService(typeof(IUserService))作为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
// 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;