Asp.net mvc 3 使用DI缓存应用程序生存期的查询

Asp.net mvc 3 使用DI缓存应用程序生存期的查询,asp.net-mvc-3,singleton,ioc-container,ninject,Asp.net Mvc 3,Singleton,Ioc Container,Ninject,使用DI容器(在本例中为Ninject)是否有可能——或者更确切地说,明智的做法是在整个应用程序生命周期(或者至少在刷新之前)缓存经常使用的对象 举个例子,假设我有一个模板。有许多模板对象,但每个用户将继承至少最低级别的对象。这是不可变的,如果不更新连接到它的所有内容,它将永远不会更改(因此它只会根据管理需求更改,而不会基于用户输入)。不断地在数据库中查询我知道没有改变的信息似乎是愚蠢的 缓存这项工作最好在我的IoC容器中完成,还是应该外包给其他人 我已经将ISessionFactory(nHi

使用DI容器(在本例中为
Ninject
)是否有可能——或者更确切地说,明智的做法是在整个应用程序生命周期(或者至少在刷新之前)缓存经常使用的对象

举个例子,假设我有一个
模板
。有许多
模板
对象,但每个用户将继承至少最低级别的对象。这是不可变的,如果不更新连接到它的所有内容,它将永远不会更改(因此它只会根据管理需求更改,而不会基于用户输入)。不断地在数据库中查询我知道没有改变的信息似乎是愚蠢的

缓存这项工作最好在我的IoC容器中完成,还是应该外包给其他人

我已经将
ISessionFactory
nHibernate
)存储为单例。但这有点不同,因为它不包括对数据库的查询,只包括打开和关闭
ISession
对象的后端

所以基本上我会这样做

static class Immutable
{
 [Inject]
 public IRepository<Template> TemplateRepository { get; set; }

 public static ITemplate Template { get; set; }

 public void Initialize()
 {
  if(Immutable.Template == null)
  {
   Immutable.Template = TemplateRepository.Retrieve(1); // obviously better logic here.
  }
}

class TemplateModule : Module
{
 public void Load()
 {
   Bind<ITemplate>().ToMethod(() => Immutable.Initialize())InSingletonScope();
 }
}
静态类不可变
{
[注入]
公共IRepository TemplateRepository{get;set;}
公共静态ITemplate模板{get;set;}
公共无效初始化()
{
if(Immutable.Template==null)
{
Immutable.Template=TemplateRepository.Retrieve(1);//这里的逻辑显然更好。
}
}
类TemplateModule:Module
{
公共空荷载()
{
Bind().ToMethod(()=>Immutable.Initialize())InSingletonScope();
}
}

这是一种糟糕的方法吗?如果是,有人能推荐一种更智能的方法吗?

我通常会避免在代码中使用
静态和空检查-默认情况下创建没有单例连接的普通类,并通过容器将该方面分层。同上,消除对属性注入的依赖-构造函数注入是alw除非你别无选择,否则一切都会好起来

i、 e:

这样注册:

class TemplateManager
{
 readonly IRepository<Template> _templateRepository;

 public TemplateManager(IRepository<Template> templateRepository)
 {
     _templateRepository = templateRepository;
 }

 ITemplate _cachedRootTemplate;    
 ITemplate FetchRootTemplate()
 { 
     if(_cachedRootTemplate==null)
           _cachedRootTemplate = LoadRootTemplate();
     return _cachedRootTemplate;
 }

 ITemplate LoadRoot()
 {
  return _templateRepository.Retrieve(1); // obviously better logic here.
 }
}
class TemplateModule : Module
{
 public void Load()
 {
   Bind<TemplateManager>().ToSelf().InSingletonScope();
 }
}
class TemplateConsumer
{
 readonly TemplateManager _templateManager;

 public TemplateConsumer(TemplateManager templateManager)
 {
     _templateManager = templateManager;
 }

 void DoStuff()
 {
      var rootTempalte = _templateManager.FetchRootTemplate();
《野性投机》:我也会考虑在容器中没有一个独立的知识库。
可能与工作单位有各种联系)。相反,我希望TemplateRepository是一个寿命更长的东西,不与ORM层和工作单元耦合。如果拥有一个存储库和一个管理器,而这些存储库和管理器都不能独立完成任何定义良好的工作,这不是一个好迹象-存储库不应该只是一个表数据网关-它应该能够成为一个聚集根(如Templ)的位置ATE被缓存并整理在一起。但是在没有上下文的情况下抛出类似的东西之前,我必须了解更多关于您的代码库的信息!

所以您是说要创建一个容器来获取管理器,但是管理器独立于容器,以便在
ISession
完成时可以处理管理器,但是ntainer(“
Consumer
”)可以保留检索到的singleton吗?@Stacey:我想是的。总之,我基本上是在重新启动SRP-试着将诸如终身(singleton)等许多责任分开,缓存,管理层次关系的遍历和数据访问到不同的概念中-每件事都应该只有一个主要的改变原因。所有这些都必须保持在合理的范围内-这并不意味着每件事每次都需要成为一个婴儿类-你只需要寻找机会来简化问题b容器(我仅将该术语用作DI工具的通用术语)可以很容易地成为一把金锤,可以同时解决所有这些需求的各个方面,但让它这样做意味着a)你最终会得到毛茸茸的DI配置,这很难理解,因为所有这些重叠的目标/职责b)你没有积极地将代码中的重要概念驱动到抽象中,例如f函数和类。简言之,是的,我的意思是,如果你有一个做缓存的类,并且它与生命周期无关,那么你可以在上面分层一个生命周期/作用域,如果你想做一些事情,比如在缓存数据脏的时候转储缓存数据,那么你不需要重构这个世界就可以轻松地对它进行更改。缓存的最后一点是一般来说,在测量/探查器告诉您您需要它之前,您不应该这样做(即使在本例中它看起来像是一个打开和关闭的案例)。
class TemplateConsumer
{
 readonly TemplateManager _templateManager;

 public TemplateConsumer(TemplateManager templateManager)
 {
     _templateManager = templateManager;
 }

 void DoStuff()
 {
      var rootTempalte = _templateManager.FetchRootTemplate();