【发布时间】:2016-02-18 05:31:47
【问题描述】:
我有一个使用 Unity 块的 WCF 服务。
使用服务定位器模式解决依赖关系。
此服务每秒会收到多个请求,主要是在工作时间。托管它的应用程序池不托管其他进程,并在每天凌晨 2 点回收。
自安装以来,我们已经看到此错误发生了 3 次(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>
更新添加
每个服务实现都有两个 ctor - 一个没有参数,另一个带有用于测试的参数注入。 WCF 调用的无参数 ctor 包含对辅助类 (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
【问题讨论】:
-
您能否显示更多关于何时调用
LoadConfiguration的信息(和代码)?例如它驻留在什么文件和方法上? -
@RandyLevy 我会把它添加到原始问题中,给我 5 分钟的时间输入。
-
感谢您更新代码。你的代码绝对不是线程安全的,所以我要做的第一件事就是修复它。看起来你想要一个单例(使用共享函数),但你并没有阻止多个线程访问共享的 _unityContainer。如果使用 .NET 4+,您可以使用
Lazy<T>以线程安全的方式初始化容器。如果没有,那么您可以在以下位置调整其他单例方法之一:csharpindepth.com/Articles/General/Singleton.aspx。 -
@RandyLevy 这怎么不是线程安全的?容器在启动时加载,从容器读取不需要锁定,因为它没有被修改?
标签: .net wcf unity-container enterprise-library