问题描述
前几天我曾与ASP.Net线程这个问题。我想有每个Web请求一个单独的对象。我确实需要这对我的工作单位。我想,这样的身份地图是有效的通过了要求每个实例化Web请求的工作单元。这样,我可以用一个IoC透明地注入我自己IUnitOfWork我的库类,我可以使用相同的实例来查询,然后更新我的实体。
A few days ago I had this issue with ASP.Net threading. I wanted to have a singleton object per web request. I actually need this for my unit of work. I wanted to instantiate a unit of work per web request so that identity map is valid through out the request. This way I could use an IoC to inject my own IUnitOfWork to my repository classes transparently, and I could use the same instance to query and then update my entities.
由于我使用的统一,我错误地使用了PerThreadLifeTimeManager。我很快意识到,ASP.Net线程模型不支持我想acheive什么。基本上,它采用了theadpool并回收线程,这意味着我得到每线程间的UnitOfWork!不过,我想是每web请求一个工作单元。
Since I am using Unity, I mistakenly used PerThreadLifeTimeManager. I soon realised that ASP.Net threading model does not support what I want to acheive. Basically it uses a theadpool and recycles threads, and that means that I get one UnitOfWork per thread!! However, what I wanted was one unit of work per web request.
google搜索的一点给我的。这正是我想要的;除了这是很容易acheive团结一部分。
A bit of googling gave me this great post. That was exactly what I wanted; except for the unity part which was quite easy to acheive.
这是我的执行PerCallContextLifeTimeManager团结:
This is my implementation for PerCallContextLifeTimeManager for unity:
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()
{
}
}
当然,我用这个来我工作的单位有一个类似的code寄存器:
And of course I use this to register my unit of work with a code similar to this:
unityContainer
.RegisterType<IUnitOfWork, MyDataContext>(
new PerCallContextLifeTimeManager(),
new InjectionConstructor());
希望这样可以节省别人一点时间。
Hope it saves someone a bit of time.
推荐答案
巧妙的解决办法,但LifetimeManager的每个实例应该使用一个唯一的密钥,而不是一个常量:
Neat solution, but each instance of LifetimeManager should use a unique key rather than a constant:
private string _key = string.Format("PerCallContextLifeTimeManager_{0}", Guid.NewGuid());
否则,如果您有PerCallContextLifeTimeManager注册了多个对象,他们共享同一个密钥来访问CallContext中,你不会得到你的预期目标了。
Otherwise if you have more than one object registered with PerCallContextLifeTimeManager, they're sharing the same key to access CallContext, and you won't get your expected object back.
另外值得一实施RemoveValue确保对象清理:
Also worth implementing RemoveValue to ensure objects are cleaned up:
public override void RemoveValue()
{
CallContext.FreeNamedDataSlot(_key);
}
这篇关于辛格尔顿每调用上下文(网络请求)在Unity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!