我有一个使用Unity块的WCF服务。
使用服务定位器模式解析依赖关系。
此服务在主要工作时间内每秒收到几个请求。托管它的应用程序池不会托管任何其他进程,并且每天凌晨2点进行回收。
自安装以来,我们已经看到过这种错误三次(1月初,2月初,今天),因此非常间歇性。
我们得到的例外是:
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, ServiceContracts.IAuthService, is an interface and cannot be constructed. Are you missing a type mapping?
通过调用Unity容器上的.Resolve<T>
解决了这个问题。容器是静态的,并在第一次被
_unityContainer = New Microsoft.Practices.Unity.UnityContainer()
_unityContainer.AddNewExtension(Of Microsoft.Practices.Unity.InterceptionExtension.Interception)()
_unityContainer.AddNewExtension(Of Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity.EnterpriseLibraryCoreExtension)()
_unityContainer.LoadConfiguration()
我不相信配置有任何问题,因为这只发生在一个安装站点(服务安装在其他位置没有问题)。
Unity版本为2.0.414.0
。
Unity配置通过web.config发生,例如:
<unity>
<container>
<register type="ServiceContracts.IAuthService, ServiceContracts" mapTo="ServiceContracts.AuthService, ServiceImp" />
</container>
</unity>
更新以添加
每个服务实现都有两个ctors - 一个没有参数,另一个有param注入,用于测试。 WCF调用的无参数ctor包含对helper类(Unity
)的调用,该类是Unity容器上的一个非常薄的包装器,并实现了服务定位器模式。
因此,对于包装所描述的IAuthService的类,ctor看起来像这样:
private IAuthService _authService;
public AuthWrapper()
{
_authService = Unity.Resolve<IAuthService>();
}
VB.NET中的Unity助手类看起来像这样:
Public NotInheritable Class Unity
Private Shared _unityContainer As IUnityContainer
Public Shared Function Resolve(Of T)() As T
If _unityContainer Is Nothing Then Call configure()
Return _unityContainer.Resolve(Of T)()
End Function
Private Shared Sub configure()
_unityContainer = New Microsoft.Practices.Unity.UnityContainer()
_unityContainer.LoadConfiguration()
End Sub
End Class
答案 0 :(得分:0)
InvalidOperationException
- 这表示该接口未在容器中注册。
为什么会这样?如果LoadConfiguration
仅在启动时调用一次,那么看起来注册在容器中丢失(我以前从未见过)或者容器已经创建但LoadConfiguration
没有被调用然而。后者似乎更有可能。也许应用程序池已关闭/回收(超时?),然后两个请求同时进入。在引导期间存在竞争条件是可能的(由于发布的代码未完成,因此无法确定)。
e.g。请求#1进来并创建容器。同时请求#2进入,发现容器已创建并尝试解析。但是,在请求#1完成加载容器配置之前,请求#2的解析发生。该场景解释了所描述的行为,但是,如果没有更多信息,则不清楚这是否是这种情况下实际发生的情况。