1 回答
TA贡献1884条经验 获得超4个赞
让我们从特定于 ASP.NET 的IUserContext注册开始:
container.Register<IUserContext>(() => {
User user = null;
try {
user = HttpContext.Current?.Session[USER_CONTEXT] as IUser;
}
catch { }
return new UserContext(user);
});
这种注册是有问题的,因为UserContext组件依赖于运行时数据的可用性,而正如此处所述,对象图的创建应该与运行时数据分开,并且运行时数据应该流经系统。
换句话说,您应该将您的UserContext课程重写为以下内容:
public class AspNetUserContext : IUserContext
{
User CurrentUser => (User)HttpContext.Current.Session[USER_CONTEXT];
}
这允许IUserContext按如下方式注册此特定于 ASP.NET 的实现:
container.RegisterInstance<IUserContext>(new AspNetUserContext());
当然,前面的并没有解决你的Windows Service中的问题,但是前面的确实为解决这个问题打下了基础。
对于 Windows 服务,您还需要自定义实现(适配器):
public class ServiceUserContext : IUserContext
{
User CurrentUser { get; set; }
}
这个实现要简单得多,这里ServiceUserContext的CurrentUser属性是一个可写属性。这优雅地解决了您的问题,因为您现在可以执行以下操作:
// Windows Service Registration:
container.Register<IUserContext, ServiceUserContext>(Lifestyle.Scoped);
container.Register<ServiceUserContext>(Lifestyle.Scoped);
// Code in the new Thread:
using (container.BeginLifetimeScope())
{
.....
var userContext = container.GetInstance<ServiceUserContext>();
// Set the user of the scoped ServiceUserContext
userContext.CurrentUser = GetUserContext(message);
var handler = container.GetInstance<IHandleMessages<SomeMessage>>();
handler.Handle(message);
.....
}
在这里,解决方案也是将对象图的创建与运行时数据的使用分开。在这种情况下,运行时数据在构造(即使用userContext.CurrentUser = GetUserContext(message))后提供给对象图。
- 1 回答
- 0 关注
- 64 浏览
添加回答
举报