【发布时间】:2018-09-29 21:21:37
【问题描述】:
我有一些客户端(Web 和桌面应用程序)必须连接到一些服务,这些服务是托管在 Windows 服务中的 WCF 服务。这些服务必须从一个或多个数据库中获取数据,但由客户端决定从哪个数据库中可以定义一个或多个相同类型的数据库。
我在服务中设置了数据上下文、存储库、业务管理器和服务实现。 Datacontext 由 SimpleInjector 容器注入(我也尝试使用 Unity),当然,容器中的注册发生在创建 ServiceHosts 之前,它们是在上下文模式 Single 下创建的(也尝试每次调用和每次会话)。
我编写了 IDispatchMessageInspector 的实现,它将拦截所有 SOAP 消息并读取消息头并根据消息头中的值设置数据上下文的数据库连接字符串。 但这会导致问题,因为它不是“线程安全的”,或者至少当一个调用尚未完成时,下一个调用可能会将另一个连接字符串设置为相同的数据上下文,从而把它搞砸。
所以,我正在尝试根据调用(异步、wcf 生活方式)注册它,但因为这是 Windows 服务,它不会关闭并且容器的范围不正确。
在这种情况下我可以做些什么来让它发挥作用?
容器创建和服务主机启动:
var container = new Container();
//container.Options.DefaultLifestyle = new AsyncScopedLifestyle();
DIContainer.SetDI(container);
serviceHosts.Add(new ServiceHost(typeof(LoginService)));
serviceHosts.Add(new ServiceHost(typeof(IdentityService)));
foreach (var serviceHost in serviceHosts)
{
serviceHost.Open();
}
DbContext 的注册:
container.RegisterInstance<CSI.AuthServices.DataAccess.EF.Interfaces.ISecurityContext>(new CSI.AuthServices.DataAccess.EF.SecurityContext());
用于读取 SOAP 消息头并设置数据库连接字符串的拦截器:
ISecurityContext securityContext = m_Container.GetInstance<ISecurityContext>();
var sqlConn = new SqlConnectionStringBuilder
{
DataSource = @"DEV_TEST_SERVER\SQL2017",
InitialCatalog = "COMMON",
IntegratedSecurity = true,
ConnectTimeout = 30
};
securityContext.Database.Connection.ConnectionString = sqlConn.ConnectionString;
【问题讨论】:
标签: c# wcf unity-container soa simple-injector