本文介绍了辛格尔顿每调用上下文(网络请求)在Unity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前几天我曾与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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 11:22