Can I keep an unserialisable object between requests?

谁都会走 提交于 2019-12-11 15:26:46

问题


I have created an .NET Core API project. It works but it creates a new object for each get request. Where can I save the object so that I can reuse it? I have searched Google and found Session but that only seems to store bytes or serialised bytes. I don't think I can serialise the object.

If doSomeInitialisation() takes 1 seconds, creating a new SomeLibrary at each get request when the arg1 is the same does not seem efficient and SomeLibrary is not serialisable so it cannot be stored to the Session.

[HttpGet("{arg1}/{arg2}")]
public IActionResult Get(string arg1, string arg2)
{
    var someLibrary = new SomeLibrary();
    someLibrary.doSomeInitialisation(arg1);

    return someLibrary.doSomething(arg2);
}

Requests

  • httpx://..../dog/1
  • httpx://..../dog/2
  • httpx://..../dog/3
  • httpx://..../cat/1
  • httpx://..../cat/2

I could reuse the same SomeLibrary object for the first three requests.


回答1:


I suppose you use DI in your project. First of all read this article Dependency injection in ASP.NET Core. Then you'll realize that you can use following code to register only one instance per application:

//Startup.cs
services.AddSingleton<ISomeLibrary>(new SomeLibrary());

....

//controller
public SomeController : Controller
{
    private readonly ISomeLibrary _sl;

    public SomeController(ISomeLibrary sl)
    {
        _sl = sl;
    }

    ...
}

UPDATE:

According to your last comment you can implement it like this:

public interface ISmthResolver
{
    ISomeLibrary Get(string arg);
}

...

public class SmthResolver : ISmthResolver
{
    private readonly ConcurrentDictionary<string, Lazy<ISomeLibrary>> _instances = new ConcurrentDictionary<string, Lazy<ISomeLibrary>>();

    public ISomeLibrary Get(string arg) => _instances.GetOrAdd(arg, key => new Lazy<ISomeLibrary>(() => new SomeLibrary())).Value;
}

...

services.AddSingleton<SmthResolver, ISmthResolver>();

...

public class Some
{
    public Some(ISmthResolver sr)
    {
        var sl = sr.Get("arg");
    }
}

Also read this Making ConcurrentDictionary GetOrAdd thread safe using Lazy.




回答2:


You can try on singleton pattern,but you should be considering that if it fits your demands because singleton pattern is not a good way for all classes.

 public class Singleton
    {
        private static string _locker = new object();
        private static Singleton _instance = null;
        public string SerializedString="";

        ///Constructore is called just one time !
        public Singleton(arg1){
         DoSerialization(arg1);
         }
        public static Singleton Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_locker)
                    {
                        if (_instance == null)
                        {
                            _instance = new Singleton();
                        }
                    }
                }
                return _instance;
            }
        }
    private void DoSerialization(arg1){
      this.SerializedString=JsonConvert.SerializeObject(arg1)
     }
    }

and use it like this

var SameInstance=new Singleton(arg1).Instance;
var serialized=SameInstance.SerializedString;


来源:https://stackoverflow.com/questions/58022776/can-i-keep-an-unserialisable-object-between-requests

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