我上课时在WebApi项目中设置Autofac,它看起来像:
public static class Bootstraper
{
private static IContainer _container { get; set; }
public static void Init()
{
var configuration = GlobalConfiguration.Configuration;
var builder = new ContainerBuilder();
// register WebAPI
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(configuration);
builder.RegisterHttpRequestMessage(configuration);
// register MVC
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterModule(new AutofacWebTypesModule());
// register model class
builder.RegisterType<Foo>().AsSelf().InstancePerRequest();
builder.RegisterType<FooMessage>().AsSelf().InstancePerRequest();
var container = builder.Build();
// setup WebApi Autofac resolver
var resolverAPI = new AutofacWebApiDependencyResolver(container);
configuration.DependencyResolver = resolverAPI;
// setup MVC Autofac resolver
var resolverMVC = new AutofacDependencyResolver(container);
DependencyResolver.SetResolver(resolverMVC);
_container = container;
}
public static T Resolve<T>()
{
return _container.Resolve<T>();
}
public static T ResolveInScope<T>()
{
// where scope shoud by disposed?
var scope = _container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
return scope.Resolve<T>();
}
}
Foo 和 FooMessage 类:
public class FooMessage
{
public HttpRequestMessage Request {get; private set; }
public Foo Foo { get; private set; }
public FooMessage(HttpRequestMessage requestMessage, Foo fooo)
{
Request = requestMessage;
Foo = fooo;
}
}
public class Foo
{
public static int counter = 0;
public int Index { get; private set; }
public Foo()
{
Index = counter++;
}
}
为了显示我的问题,我准备了示例控制器
public class ValuesController : ApiController
{
private FooMessage fooMessage;
private Foo foo;
public ValuesController(FooMessage fm, Foo fooo)
{
fooMessage = fm;
foo = fooo;
}
// GET api/values
public bool Get()
{
// it works but create new Foo object (resolvedFoo.Index > foo.Index)
var resolvedFoo = DependencyResolver.Current.GetService<Foo>();
// throw the exception
var resolvedFoo2 = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(Foo)) as Foo;
// throw the Exception
var resolvedFoo3 = Bootstraper.Resolve<Foo>();
// it works but create new Foo object (resolvedFoo.Index > foo.Index)
// and I don't now when dispose created scope
var resolvedFoo4 = Bootstraper.ResolveInScope<Foo>();
if (resolvedFoo.Index != foo.Index || resolvedFoo.Index != fooMessage.Foo.Index)
return false;
return true;
}
}
当创建ValuesController时,foo和fooMessage.Foo中的Index属性具有相同的值,它可以运行greate。我需要在我的bussines逻辑(InstancePerRequest)中解析Foo,FooMessage,特别是HttpRequestMessage,但我不能使用bussines构造函数来执行此操作。对于我的目的,最好的解决方案是使用Bootstraper.Resolve()但它抛出异常:
类型&#39; Autofac.Core.DependencyResolutionException&#39;的例外情况 发生在Autofac.dll但未在用户代码中处理
附加信息:没有标记匹配的范围 &#39; AutofacWebRequest&#39;从实例的范围可见 被要求了。这通常表示注册为的组件 SingleInstance()组件正在请求每HTTP请求 (或类似场景。)在Web集成下始终请求 来自DependencyResolver.Current或的依赖项 ILifetimeScopeProvider.RequestLifetime,永远不会从容器中 本身。
请帮助我理解它是如何工作的。