使用WcfOperationLifestyle时,Container.GetInstance(Type)抛出ActivationException

时间:2017-08-08 14:32:26

标签: wcf dependency-injection simple-injector

我有一个使用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

1 个答案:

答案 0 :(得分:1)

仔细检查堆栈跟踪后,我可以得出结论:async。

封面下的WcfOperationLifestyle取决于WCF的OperationContext.Current属性,但此属性具有线程关联性,并且不会与异步操作一起流动。这是必须在Simple Injector的集成库中修复的东西;它现在根本不支持异步。

相反,将装饰器包裹在处理程序周围,以启动和结束新的异步范围。这可以防止您必须一起使用WcfOperationLifestyle。请查看ThreadScopedCommandHandlerProxy<T>实施here,了解如何执行此操作(但请改用AsyncScopedLifestyle)。