ASP.NET OWIN与Singleton模式

时间:2017-11-08 13:03:47

标签: c# asp.net owin asp.net-mvc-5.2

我正在开发一个Web应用程序,我在下面的Startup.cs中实例化了一个Singleton类,以便重用(更像是进行可编程会话):

 app.CreatePerOwinContext<XYZManager>(XYZManager.Create);

但是我遇到了一个问题,一旦UserA登录应用程序,当UserB进入时,XYZManager类中的信息会被覆盖,反之亦然。

我认为问题是,他们共享相同的应用程序池,如何解决,任何黑客攻击?

同时这个方法的本质是,我希望能够在XYZManager中为当前记录的用户调用任何getter / setter方法,例如:

HttpContext.GetOwinContext().Get<XYZManager>().GetFullDetails();

但有时会根据操作为其他登录用户抛出详细信息。

 public class XYZManager : IDisposable
 {
     private static XYZManager instance  { get; set; }
     public static  XYZManager Create()
     {
        var xyzManager = instance ?? (instance = new XYZManager());
        xyzManager.ApplicationDbContext = new ApplicationDbContext();
        return xyzManager;
     }
     public string GetFullDetails () {
        return "blah blah";
     }
 }

1 个答案:

答案 0 :(得分:1)

msdn中所述,CreatePerOwinContext方法将接受工厂方法来创建类的实例(在此cas XYZManager中),并且它将为所有相同的上下文请求保留它。

HttpContext.GetOwinContext().Get<XYZManager>()

因此,每次创建新的Owin Context(收到新的http请求)时,都会调用XYZManager.Create。在您的情况下,此方法返回相同的实例,因此所有上下文将共享该实例。

根据您是否要为所有上下文共享该实例,您应该返回新的或相同的实例。另请注意,对于单例共享实例,有一个不同的Owin扩展方法可以为您保留单例。

查看此answer,因为它解释了CreatePerOwinContext方法的目的是什么,并提供了一些如何创建内部上下文共享实例的示例。

这是您创建Context共享服务的方式

public class XYZManager : IDisposable
{
     public static  XYZManager Create()
     {
         return  new XYZManager(new ApplicationDbContext());
     }
     private readonly ApplicationDbContext DbContext;

     public XYZManager(ApplicationDbContext dbContext)
     {
         DbContext = dbContext;
     }
     public string SomeInfo {get;set;}
     public string GetFullDetails () 
     {
         return dbContext.getFullDetails();
     }
     // dispose
 }

注意:由于每次创建新的owin上下文时都会创建实例,因此建议您确保处理所有非托管对象。