【发布时间】:2016-10-24 17:58:02
【问题描述】:
我正在使用带有 Autofac 的 WebAPI 并开始一个长时间运行的任务(即开即忘的东西),该任务将在 HTTP 请求的生命周期后仍然存在。因此,我想防止ApiController 在ApiController 生命周期结束后自动处理包含长时间运行任务的对象。
在 Web API 控制器中,我想使用 Owned<T> 类来注入其中一个依赖项,而不将其绑定到 ApiController 实例的 LifeTimeScope。似乎Owned<T> 是一个不错的选择,但我想从它继承,以便拥有可以使用 Moq 库模拟的虚拟(多态)Value 属性。
但是,当我从 Owned<T> 继承时,autofac 无法识别(由于反射?)我的 MyOwned<T> 并在下面抛出异常。
在“autofak.Meta”类型上使用“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”找到的任何构造函数都不能使用可用的服务和参数调用:无法解析参数“System.Func”2[System.Int32 ,autofak.MyOwned'1[autofak.Root]] root' 的构造函数'Void .ctor(System.Func'2[System.Int32,autofak.MyOwned'1[autofak.Root]])'。
这是我的顶级类,它依赖于 Root 类。
class Meta
{
public MyOwned<Root> Root { get; private set; }
public Meta(Func<int, MyOwned<Root>> root)
{
Root = root(2);
}
}
我的注册码如下:
var container = new ContainerBuilder();
container.RegisterType<child>();
container.RegisterType<grandchild>();
container.RegisterType<Root>();
container.RegisterType<Meta>();
var builder = container.Build();
是否可以从 Owned 继承并使其工作,还是我应该尝试不同的方法?
更新:
除了公认的解决方案之外,我还通过创建SingleInstance() 工厂以从根/应用程序生命周期范围创建新的LifeTimeScope 对象来遵循不同的路径。与Owned<T> 类类似,我创建了一个新类,它还为每个任务存储这个新生命周期(从根生命周期范围创建),并可以像在Owned<T> 中一样调用Dispose()。
【问题讨论】:
-
我的猜测是,您需要使用类似于配置
Owned<T>的容器注册您的MyOwned<T>类。 -
我认为
Owned<T>除了注册类型之外,我们不需要特殊注册,对吗? -
是的,它是为
Owned<T>内置的,但你的不是。找到Owned<T>在 Autofac 的源代码中注册的位置应该不会太复杂,并且基本上为您的课程复制它。 -
它使用
IRegistrationSource注册here。 -
你的意思是把这段代码复制到我的项目中?