【问题标题】:Can I keep an unserialisable object between requests?我可以在请求之间保留不可序列化的对象吗?
【发布时间】:2019-09-20 19:50:26
【问题描述】:

我创建了一个 .NET Core API 项目。它可以工作,但它会为每个 get 请求创建一个新对象。我可以在哪里保存对象以便我可以重复使用它?我搜索了谷歌并找到了Session,但这似乎只存储字节或序列化字节。我不认为我可以序列化对象。

如果 doSomeInitialisation() 需要 1 秒,则在 arg1 相同时在每个 get 请求中创建一个新的 SomeLibrary 似乎效率不高且 SomeLibrary 不可序列化,因此无法将其存储到 @ 987654329@.

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

    return someLibrary.doSomething(arg2);
}

请求

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

我可以为前三个请求重用相同的 SomeLibrary 对象。

【问题讨论】:

  • 使用控制器的静态成员来保存你的对象怎么样?
  • 我想过,但这是推荐的方式吗?
  • 考虑使用Dependency Injection 在您的SomeLibrary 对象上使用“单例”规范?
  • 它会起作用,但是在考虑推荐的方法时,由于这是 Dandre 建议的 asp 核心,您可以使用单例服务并注入控制器。

标签: c# asp.net-core asp.net-core-webapi


【解决方案1】:

我想您在项目中使用 DI。首先阅读这篇文章Dependency injection in ASP.NET Core。然后你会发现你可以使用下面的代码为每个应用注册一个实例:

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

....

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

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

    ...
}

更新:

根据您最后的评论,您可以这样实现:

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

另请阅读Making ConcurrentDictionary GetOrAdd thread safe using Lazy

【讨论】:

  • 问题是,我想缓存SomeLibrary 的多个实例。如我的 OP 所示,我想为“狗”缓存一个,为“猫”缓存一个,因此在将来的请求中,当arg 是“狗”或“猫”时,我不会创建新的SomeLibrary。如果我使用这个 DI 模式,我是否应该定义/创建一个可以容纳多个 SomeLibrary 实例的对象(例如,具有 Dictionary&lt;string, SomeLibrary&gt; 字段的类)并将其用于 AddSingleton
【解决方案2】:

你可以尝试单例模式,但你应该考虑它是否符合你的要求,因为单例模式并不是所有类的好方法。

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

并像这样使用它

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 2014-01-27
    • 2015-02-14
    • 1970-01-01
    • 2010-11-13
    相关资源
    最近更新 更多