我正在开发一个WCF项目,我在其中使用Autofac作为IoC容器,MediatR作为调解器来执行我的请求&命令。
WCF契约的“基础”实现将IMediator
的实例作为依赖关系,将与每个请求关联的工作委托给关联的处理程序。我还有几个装饰器,我将基础实现堆叠起来,用于授权和错误处理等。
如this page of Autofac documentation中所述,当您在服务实现上使用装饰器时,必须使用MultitenantServiceImplementationDataProvider
以满足WCF内部。不需要多租户相关的东西,所以它只包括:
AutofacServiceHostFactory.ServiceImplementationDataProvider = new MultitenantServiceImplementationDataProvider();
另外,在.svc
我指定了界面的限定名称,因为它受到Autofac的支持,我的基础实现上有装饰器。
现在,转到MediatR MediatR使用服务位置在给出请求时实例化适当的处理程序。更具体地说,它依赖于CSL。
没问题,因为Autofac提供了bridge to support CSL
“棘手”部分依赖于我的处理程序将DbContext
作为依赖项,并且我希望在每个WCF请求之后由Autofac处理它们。
因此,AutofacServiceLocator
必须被赋予为特定请求创建的范围,因为根范围未被处理,也不是DbContext
实例。
Autofac让您了解AutofacInstanceContext.Current
静态属性,该属性相当于ASP.NET MVC中的AutofacDependencyResolver.RequestLifetimeScope
。
到目前为止一切顺利,这是我注册ServiceLocatorProvider
Mediator
类取决于以下内容的方式:
builder
.Register(x => new ServiceLocatorProvider(() => new AutofacServiceLocator(AutofacInstanceContext.Current.OperationLifetime)))
.InstancePerLifetimeScope();
它在我的开发框中按预期工作但我在暂存环境中获得NullReferenceException
并且我真的不知道在哪里寻找 - GoogleBing没有给出相关结果。
只有与这两种环境不同的东西:
debug
元素的{li> <system.web>
属性在暂存环境中设置为false。
那是关于它的...
.NET框架与4.5.2。
有人有想法吗? 谢谢!
答案 0 :(得分:1)
通过更改:
修正了它builder
.Register(x => new ServiceLocatorProvider(() => new AutofacServiceLocator(AutofacInstanceContext.Current.OperationLifetime)))
.InstancePerLifetimeScope();
与
builder
.Register(x =>
{
var serviceLocator = new AutofacServiceLocator(AutofacInstanceContext.Current.OperationLifetime);
return new ServiceLocatorProvider(() => serviceLocator);
}
.InstancePerLifetimeScope();
我无法确切地告诉你为什么它不起作用,但我想当lambda表达式() => new AutofacServiceLocator(AutofacInstanceContext.Current.OperationLifetime)
由MediatR在内部执行时,为时已晚并且当前的操作上下文被处置或释放。
任何见解仍然会受到高度赞赏!