Nat*_*lor 6 asp.net-mvc design-patterns inversion-of-control
我仍然大多不熟悉控制反转(虽然我现在正在学习它)所以如果这是我的问题的解决方案,请告诉我,我会回过头来学习它.
我有一对控制器需要一个Session变量,自然没有什么特别的事情发生,因为Session首先工作,但这让我想知道在两个独立的控制器之间共享相关对象最干净的方法是什么.在我的特定场景中,我有一个UploadController和一个ProductController,它们相互配合使用来上传图像文件.当UploadController上传文件时,有关上传的数据存储在Session中.发生这种情况后,我需要在ProductController中访问该Session数据.如果我在两个控制器中为包含我的上传信息的Session变量创建一个get/set属性,我将能够访问该数据,但同时我将违反各种DRY,更不用说创建一个,充其量,令人困惑的设计,其中一个对象由两个完全断开连接的对象共享和修改.
你有什么建议?
确切的背景:
文件上载View将文件发布到UploadController.ImageWithpreview(),然后读取已发布的文件并将其复制到临时目录.保存文件后,另一个类生成上传图像的缩略图.然后,使用JsonResult将原始文件和生成的缩略图的路径返回到javascript回调,该回调更新页面上可以"已保存"或"已取消"的表单中的某些动态内容.无论上传的图像是保存还是被跳过,我都需要从临时目录中移动或删除它和生成的缩略图.为此,UploadController在Session维护的Queue对象中跟踪所有上传文件及其缩略图.
返回视图:在使用生成的图像缩略图填充表单后,表单将回发到ProductsController,其中标识了所选文件(目前我将文件名存储在隐藏字段中,我意识到这是一个可怕的漏洞),然后从临时目录复制到永久位置.理想情况下,我想简单地访问我存储在Session中的队列,这样表单就不需要像现在一样包含图像位置.这就是我设想我的解决方案的方式,但我会热切地倾听任何评论或批评.
我想到了几个解决方案。您可以使用映射到请求并获取/设置信息的“SessionState”类(我是从内存中执行此操作,因此这不太可能编译并且旨在传达这一点):
internal class SessionState
{
  string ImageName
  {
    get { return HttpContext.Current.Session["ImageName"]; }
    set { HttpContext.Current.Session["ImageName"] = value; }
  }
}
然后从控制器中执行以下操作:
  var sessionState = new SessionState();
  sessionState.ImageName = "xyz";
  /* Or */
  var imageName = sessionState.ImageName;
或者,您可以创建一个控制器扩展方法:
public static class SessionControllerExtensions
{
  public static string GetImageName(this IController controller)
  {
    return HttpContext.Current.Session["ImageName"];
  }
  public static string SetImageName(this IController controller, string imageName)
  {
    HttpContext.Current.Session["ImageName"] = imageName;
  }
}
然后从控制器:
  this.SetImageName("xyz");
  /* or */
  var imageName = this.GetImageName();
这当然是干的。也就是说,我不太喜欢这两种解决方案,因为我更喜欢在会话中存储尽可能少的数据(如果有的话)。但是,如果您打算保留所有这些信息,而不必从其他来源加载/识别它,那么这是我能想到的最快(最脏)的方法。我很确定有一个更优雅的解决方案,但我没有关于您想要做什么以及问题域是什么的所有信息。
请记住,在会话中存储信息时,您必须通过序列化对对象进行脱水/再水化,并且您可能无法通过这种方式获得您认为的性能。
希望这可以帮助。
编辑:响应附加信息 不确定您要在哪里部署它,但“实时”处理图像肯定会受到 DoS 攻击。我给你的建议如下——假设这是面向公众的,任何人都可以上传图像:
1) 允许用户上传图像。该图像进入处理队列,由应用程序或某些服务进行后台处理。此外,图像的名称会进入用户的个人处理队列——可能是数据库中的一个表。有关 Web 应用程序中后台处理的信息可以在 @ Schedule a job in Hosted Web Server 中找到
2) 处理这些图像,并在处理的同时显示“处理图形”。您可以在产品页面上发出 ajax 请求,检查正在处理的图像并尝试每 X 秒重新加载它们。
3) 当图像正在“处理”时,用户可以选择退出处理,假设他们是上传图像的人。这可以在显示图像的产品页面上或在单独的“用户队列”视图上使用,该视图将允许他们从考虑中删除图像。
因此,您最终会得到更多域对象,并且这些对象由队列管理。我是约定优于配置的强烈拥护者,因此应该预先定义产品图像的最终目的地。就像是:
images/products/{id}.jpg 或者,如果是集合,则为 images/products/{id}/{sequence}.jpg。
这样您就不需要知道表格中的目的地。对于所有图像都是一样的。
然后队列需要知道临时图像的上传位置以及产品 ID 是什么。队列工作人员从队列中弹出项目,处理它们,并相应地存储它们。
我知道这听起来比你最初的意图更“结构化”,但我认为它更干净一些。