几天前,我遇到了 ASP.Net 线程的问题。我希望每个网络请求都有一个单例对象。我实际上需要这个来完成我的工作单位。我想为每个 Web 请求实例化一个工作单元,以便身份映射在整个请求过程中都有效。这样我就可以使用 IoC 将我自己的 IUnitOfWork 透明地注入到我的存储库类中,并且我可以使用相同的实例来查询然后更新我的实体。
由于我使用的是Unity,所以我错误地使用了PerThreadLifeTimeManager。我很快意识到 ASP.Net 线程模型不支持我想要实现的目标。基本上它使用线程池并回收线程,这意味着我每个线程获得一个 UnitOfWork!然而,我想要的是每个网络请求一个工作单元。
一些谷歌搜索给了我这篇很棒的文章 http://dotnetslackers.com/Community/blogs/simoneb/archive/2006/08/21/The-ASP.NET-Singleton_2D00_per_2D00_Request-pattern.aspx。这正是我想要的;除了很容易实现的统一部分。
这是我对 PerCallContextLifeTimeManager 的统一实现:
public class PerCallContextLifeTimeManager : LifetimeManager
{
private const string Key = "SingletonPerCallContext";
public override object GetValue()
{
return CallContext.GetData(Key);
}
public override void SetValue(object newValue)
{
CallContext.SetData(Key, newValue);
}
public override void RemoveValue()
{
}
}
当然,我用它来注册我的工作单元,代码如下:
unityContainer
.RegisterType<IUnitOfWork, MyDataContext>(
new PerCallContextLifeTimeManager(),
new InjectionConstructor());
希望它可以节省一些人的时间。
很好的解决方案,但是 LifetimeManager 的每个实例都应该使用唯一的键而不是常量:
private string _key = string.Format("PerCallContextLifeTimeManager_{0}", Guid.NewGuid());
否则,如果您向 PerCallContextLifeTimeManager 注册了多个对象,它们将共享相同的密钥来访问 CallContext,并且您将无法取回预期的对象。
还值得实现RemoveValue来确保对象被清理:
public override void RemoveValue()
{
CallContext.FreeNamedDataSlot(_key);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)