我在当前的项目中遇到了 Glass Mapper 的问题,这是我以前从未遇到过的。
在 Sitecore 初始化之后,我的 GlassContext (
Database
) 中的 ISitecoreContext
属性为空。
// After Sitecore initialization, sometimes the glass context database is not initialized yet.
if (this.glassContext == null || this.glassContext.Database == null)
{
this.glassContext = DependencyInjection.Container.Resolve<ISitecoreContext>();
// Now I have a valid this.glassContext.Database ...
}
当我向我的 DI 框架(Windsor,所以 Glass 的默认设置)询问一个实例时,它会返回一个具有有效数据库属性的实例。
目前我正在检索任何项目之前进行此检查,它只需要一次此检查(之后它很好直到下一次初始化),但真的很想知道是什么导致了这个。
可能有趣的是:所有物品请求(获取物品、铸造物品等)都是通过一项服务完成的,该服务在其构造函数中初始化
ISitecoreContext
。ItemService
有生命周期 Singleton,ISitecoreContext
有生命周期 Transient
我认为您的
ItemService
是在Sitecore具有有效上下文之前首次注入的,因此Glass也不能具有有效上下文(数据库)。因为你的 ItemService
有一个 Singleton 生命周期,所以构造函数只被调用一次,并且 ISitecoreContext
的解析也完成一次。这意味着,如果您的 ItemService
在 Sitecore 具有有效上下文之前第一次得到解决,那么您的 glassContext
将是 null
。在 Singleton实例中手动设置
glassContext
属性后,下次它不会为空(但可能无效,因为您在另一个请求中)。
我建议您将两个依赖项设置为
Transient
或 PerWebRequest
.
如其他评论所述,有时这是由于未指定适当的生活方式。如果您没有找到释放它的合适方法,Transient 可能会给您带来内存泄漏。我个人经常使用 Glass Mapper 附带的 NoTrackLifestyle,因为它的行为更像是来自其他容器的 Transient。
在某些情况下,您可能会过早尝试解析服务,尤其是在管道条目中运行时会发生这种情况,其中请求的上下文尚未解析。在这些实例中,您可以使用指定数据库和/或其名称作为依赖项的命名实例。
请记住,在所有情况下,sitecore 上下文/服务默认依赖于 CONTEXT 数据库,如果 Sitecore 尚未解决它 - glass 也不会。
当它与新的 Glass Delegate 功能一起使用时,我发现有时有必要依赖延迟获取服务的工厂实现,它并不完美,但可以达到目的,因为流畅的配置通常没有上下文在实例化时可用。通过添加一个小工厂,可以延迟到真正调用委托代码的时候。
public interface ISitecoreServiceFactory
{
// Gets the Sitecore service from the container
ISitecoreService GetService();
}
有时在使用 Glass 创建 SPEAK / Sheer UI 对话框时也会出现这种情况。