我正在使用带有Autofac的WebAPI并启动一个长时间运行的任务(激活和遗忘的东西),这些任务将在HTTP请求的生命周期后生效。因此,在ApiController
生命周期结束后,我想阻止ApiController
自动处理包含长时间运行任务的对象。
在Web API控制器中,我想使用Owned<T>
类来注入其中一个依赖项,而不将其绑定到LifeTimeScope
实例的ApiController
。似乎Owned<T>
是一个很好的选择,但是我想继承它,以便拥有虚拟(多态)Value
属性,我可以使用Moq库进行模拟。
但是,当我从Owned<T>
继承时,autofac无法识别(由于反射?)我的MyOwned<T>
并抛出以下异常。
没有任何构造函数与&#39; Autofac.Core.Activators.Reflection.DefaultConstructorFinder&#39;在类型&#39; autofak.Meta&#39;可以使用可用的服务和参数调用:无法解析参数&#39; System.Func&#39; 2 [System.Int32,autofak.MyOwned&#39; 1 [autofak.Root]] root&#39;构造函数&#39; Void .ctor(System.Func&#39; 2 [System.Int32,autofak.MyOwned&#39; 1 [autofak.Root]])&#39;。
这是我依赖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>
类相似,我创建了一个新类,它还为每个任务存储了这个新生命周期(从根生命周期范围创建),并且可以像Dispose()
一样调用Owned<T>
。 / p>
答案 0 :(得分:2)
执行所需操作的最简单方法是创建一个使用Owned<T>
的新组件,而不是继承自Owned<T>
public interface IOwned<T> : IDisposable
{
T Value { get; }
}
public class MyOwned<T> : IOwned<T>
{
public MyOwned(Owned<T> owned)
{
this._owned = owned;
}
private readonly Owned<T> _owned;
public virtual T Value
{
get
{
return this._owned.Value;
}
}
public void Dispose()
{
this._owned.Dispose();
}
}
然后使用RegisterGeneric
方法和ExternallyOwned
注册您的组件。
builder.RegisterGeneric(typeof(MyOwned<>))
.As(typeof(IOwned<>))
.ExternallyOwned();
您需要将其声明为ExternallyOwned
,因为如果没有此 Autofac 将尝试将此组件置于其ILifetimeScope
的末尾,并Owned<T>
的目标是让你决定何时处理组件。
另一个选择是创建自己的Owned<T>
组件,这个组件要复杂得多,因为您需要实施IRegistrationSource
来管理ILifetimeScope
创建的子Owned<T>
} component。