Safe to use a nancy module property as 'per-request' storage?

僤鯓⒐⒋嵵緔 提交于 2019-12-11 13:43:08

问题


Aside from being a bad, bad pattern in general, are there any ramifications of doing something like this to store an object as a property on the nancy module for the life of the request? Everything looks okay but not sure if this will result in any weirdness at scale... ie, cross-talk between requests, memory leaks, general shenanigans.

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

}

回答1:


As @StevenRobbins said, you can, but the question is - why? For the snipped you provided, using local variable in the constructor is just enough.

I can envision few other reasons to want to have this:

  1. Your route(s) use a private methods to do their work. Then a private readonly field will work (for the same reasons, each module is constructed per request). Or even better, make these private functions to accept myThing as parameter, and still use local var in ctor.

  2. You want to access this outside of the module - it's better to create your own class to hold this outside the module. Register it "per request" and have a beforerequest hook to fill the data, and inject into whatever other functionality needs it.

To elaborate on (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{.....};
    }
}

Now, anywhere in the chain (need to have the parts registered per request), you can inject the bag and use the thing :)

You can even inject it in the module if you need the data there.




回答2:


You should be fine doing that, modules are constructed per request - there should be no need to use a before hook though, just stick that code in the start of your constructor as if you would when setting a property from a constructor parameter.



来源:https://stackoverflow.com/questions/29529022/safe-to-use-a-nancy-module-property-as-per-request-storage

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!