几天前,我遇到了一个关于ASP.NET线程的问题.我希望每个Web请求都有一个单例对象.我的工作单位确实需要这个.我想 for each Web请求实例化一个工作单元,这样身份映射在整个请求过程中都是有效的.这样,我就可以使用IOC透明地将我自己的IUnitOfWork注入到我的存储库类中,并且我可以使用相同的实例来查询和更新我的实体.

因为我使用的是Unity,所以我错误地使用了PerThreadLifeTimeManager.我很快意识到ASP.Net线程模型不支持我想要实现的目标.基本上,它使用一个线程池并回收线程,这意味着我每个线程有一个工作单元!!然而,我想要的是每个web请求一个工作单元.

在谷歌上搜索一下,我得到了this great post分.这正是我想要的;除了很容易实现的统一部分.

这是我对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()
    {
    }
}

当然,我用这个来注册我的工作单元,代码如下:

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);
}

Asp.net相关问答推荐

如何处理当前文件中基本文件中的S onClick方法

Windows 命令行中的/p:是什么意思

如何在 ASP.Net Core 中验证上传的文件

创建项目 ASP.NET Core (.NET Core) 和 ASP.NET Core (.NET Framework) 有什么区别

log4net 记录所有未处理的应用程序错误

如何将 viewbag 显示为 html?

无法获取项目引用的依赖项

无法从 App_code 文件夹中找到类型或命名空间

RestSharp 不反序列化 JSON 对象列表,始终为 Null

Gridview ItemTemplate 中多个判断字段的最佳技术?

部署后网站需要强制刷新

免费的 ASP.Net 和/或 CSS 主题

.NET 上的 HTTP/2(HTTP2 或 SPDY)

ASP.NET 中的全局资源与本地资源

在 Android/Java 和 C# 中计算 SHA256 哈希

ServiceStack 示例应该以什么顺序被理解?

在后面的代码中删除 css 类

在 ASPNET 标识 2.0 中禁用用户

将 html 标记从 jquery 发布调用发送到 asp.net 页面时,从客户端检测到潜在危险的 Request.QueryString 值

无法使用 ip:port 访问 WEB API,但可以在 VS 调试模式下使用 localhost:port