使用 nancy 模块 属性 作为 'per-request' 存储安全吗?
Safe to use a nancy module property as 'per-request' storage?
除了一般来说是一个糟糕的、糟糕的模式之外,在请求的生命周期内,做这样的事情将对象作为 属性 存储在 nancy 模块上是否有任何后果?一切看起来都很好,但不确定这是否会导致任何规模的怪异......即请求之间的串扰、内存泄漏、一般恶作剧。
public class APIModule : NancyModule
{
public SomeConvolutedThing MyThing { get; set; }
public APIModule()
{
Before += ctx => {
try
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(HttpContext.Current.Request.Cookies["MyThing"].Value);
MyThing = JsonConvert.DeserializeObject<SomeConvolutedThing>(ticket.UserData);
}
catch
{
MyThing = null;
}
return null;
};
Get["/api/callit"] = parameters => {
// check on status of MyThing before deciding what to return
};
}
}
你这样做应该没问题,模块是根据请求构建的——虽然应该不需要使用 before 钩子,只需将该代码粘贴在构造函数的开头,就像设置 [=12 时一样=] 来自构造函数参数。
正如@StevenRobbins 所说,你可以,但问题是 - 为什么?对于您提供的片段,在构造函数中使用局部变量就足够了。
我想不出其他几个想要拥有这个的理由:
您的路由使用私有方法来完成它们的工作。然后私有只读字段将起作用(出于同样的原因,每个模块都是根据请求构建的)。或者更好的是,让这些私有函数接受 myThing 作为参数,并且仍然在 ctor 中使用局部变量。
您想在模块外访问它 - 最好创建您自己的 class 以将其保存在模块外。注册它 "per request" 并有一个 beforerequest 钩子来填充数据,并注入到任何其他需要它的功能中。
详细说明(2):
public interface IMyThingBag
{
MyThing MyThing{get;set;}
}
public class MyBagFiller : IRequestStartup
{
private readonly IMyThingBag _bag;
public MyBagFiller(IMyThingBag bad)
{
_bad = bag;
}
public void Initialize(IPipelines pipelines, NancyContext context)
{
_bag.MyThing = new MyThing{.....};
}
}
现在,链中的任何地方(需要根据请求注册部件),您可以注入包并使用东西:)
如果你需要那里的数据,你甚至可以将它注入到模块中。
除了一般来说是一个糟糕的、糟糕的模式之外,在请求的生命周期内,做这样的事情将对象作为 属性 存储在 nancy 模块上是否有任何后果?一切看起来都很好,但不确定这是否会导致任何规模的怪异......即请求之间的串扰、内存泄漏、一般恶作剧。
public class APIModule : NancyModule
{
public SomeConvolutedThing MyThing { get; set; }
public APIModule()
{
Before += ctx => {
try
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(HttpContext.Current.Request.Cookies["MyThing"].Value);
MyThing = JsonConvert.DeserializeObject<SomeConvolutedThing>(ticket.UserData);
}
catch
{
MyThing = null;
}
return null;
};
Get["/api/callit"] = parameters => {
// check on status of MyThing before deciding what to return
};
}
}
你这样做应该没问题,模块是根据请求构建的——虽然应该不需要使用 before 钩子,只需将该代码粘贴在构造函数的开头,就像设置 [=12 时一样=] 来自构造函数参数。
正如@StevenRobbins 所说,你可以,但问题是 - 为什么?对于您提供的片段,在构造函数中使用局部变量就足够了。
我想不出其他几个想要拥有这个的理由:
您的路由使用私有方法来完成它们的工作。然后私有只读字段将起作用(出于同样的原因,每个模块都是根据请求构建的)。或者更好的是,让这些私有函数接受 myThing 作为参数,并且仍然在 ctor 中使用局部变量。
您想在模块外访问它 - 最好创建您自己的 class 以将其保存在模块外。注册它 "per request" 并有一个 beforerequest 钩子来填充数据,并注入到任何其他需要它的功能中。
详细说明(2):
public interface IMyThingBag
{
MyThing MyThing{get;set;}
}
public class MyBagFiller : IRequestStartup
{
private readonly IMyThingBag _bag;
public MyBagFiller(IMyThingBag bad)
{
_bad = bag;
}
public void Initialize(IPipelines pipelines, NancyContext context)
{
_bag.MyThing = new MyThing{.....};
}
}
现在,链中的任何地方(需要根据请求注册部件),您可以注入包并使用东西:)
如果你需要那里的数据,你甚至可以将它注入到模块中。