我有一个使用SimpleInjector的WebAPI服务。我使用AsyncScopedLifestyle
为我的作用域依赖项设置了这个,其中一个依赖项是我的实体框架DataContext
。我服务中的很多东西都依赖于DataContext
,并且它通常使用构造函数注入注入我的MediatR处理程序 - 这很有效。另外,我有一些区域需要在给定类型(作为字符串)的情况下创建对象的实例,因此我创建了一个自定义激活器类(ResolvingActivator
),其配置为{{1 }}:
在我的容器引导代码中:
Container.GetInstance(Type)
然后我可以使用以下方法创建对象:
ResolvingActivator.Configure(container.GetInstance);
当我使用WebAPI时,上述功能完美无缺。
项目的另一部分是使用WCF的遗留API。我已经将其实现为翻译层,我将旧的消息格式转换为新的消息格式,然后将消息分发给Mediator;然后我将响应(以新格式)转换回旧格式并将其返回给调用者。因为我需要在我的WCF服务中访问Mediator,所以我在它们的构造函数中注入它,并使用ResolvingActivator.CreateInstance<T>(typeName)
包让SimpleInjector提供服务的SimpleInjector.Integration.Wcf
构建实例。我也创建了混合生活方式,所以我可以为我的WebAPI和WCF服务使用相同的容器:
SimpleInjectorServiceHostFactory
这适用于某些调用,但是当调用最终调用我的container.Options.DefaultScopedLifestyle = Lifestyle.CreateHybrid(
new AsyncScopedLifestyle(),
new WcfOperationLifestyle());
类时,我会抛出ResolvingActivator
,并显示以下消息:
DataContext注册为“Hybrid Async Scoped / WCF Operation”生活方式,但是在活动(混合异步Scoped / WCF操作)范围的上下文之外请求实例。
由于我在进行WCF调用时只收到此错误,我想知道我的配置是否有问题。简而言之,这将有效:
ActivationException
但这不会:
public class SomeClass
{
private readonly DataContext db;
public SomeClass(DataContext db)
{
this.db = db;
}
public bool SomeMethod() => this.db.Table.Any();
}
我出错的任何想法?
编辑:这是来自public class SomeClass
{
public bool SomeMethod()
{
// Code behind is calling container.GetInstance(typeof(DataContext))
var db = ResolvingActivator.CreateInstance<DataContext>();
return db.Table.Any();
}
}
:
ActivationException
在此处使用完整堆栈跟踪:https://pastebin.com/0WkyHGKv
答案 0 :(得分:1)
仔细检查堆栈跟踪后,我可以得出结论:async。
封面下的WcfOperationLifestyle
取决于WCF的OperationContext.Current
属性,但此属性具有线程关联性,并且不会与异步操作一起流动。这是必须在Simple Injector的集成库中修复的东西;它现在根本不支持异步。
相反,将装饰器包裹在处理程序周围,以启动和结束新的异步范围。这可以防止您必须一起使用WcfOperationLifestyle
。请查看ThreadScopedCommandHandlerProxy<T>
实施here,了解如何执行此操作(但请改用AsyncScopedLifestyle
)。