我一直在使用ASP.NET MVC RC2中的DI支持。動作在ASP.NET MVC 3 RC2中使用StructureMap過濾依賴注入
我已經爲NHibernate實現了每個請求的會話,並且需要將ISession
注入到我的「工作單元」操作篩選器中。
如果我引用StructureMap容器直接(ObjectFactory.GetInstance),或使用DependencyResolver讓我的會話實例,一切工作正常:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
但是,如果我試圖用我的StructureMap
過濾器供應商(繼承FilterAttributeFilterProvider
)我在提交請求結束時提交NHibernate事務時遇到了問題。
就好像ISession
對象正在被請求之間共享。我經常看到這一點,因爲我的所有圖像都是通過MVC控制器加載的,所以我可以在正常頁面加載時創建20個左右的NHibernate會話。
添加以下到我的行爲過濾器:
ISession Session {
get { return DependencyResolver.Current.GetService<ISession>(); }
}
public ISession SessionTest { get; set; }
public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext) {
bool sessionsMatch = (this.Session == this.SessionTest);
SessionTest使用StructureMap過濾器提供商注入。
我發現在包含20個圖像的頁面上,對於2-3個請求,「sessionsMatch」爲false。
會話管理我的StructureMap配置如下:
For<ISessionFactory>().Singleton().Use(new NHibernateSessionFactory().GetSessionFactory());
For<ISession>().HttpContextScoped().Use(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());
在Global.asax中我把在每個請求的末尾以下內容:
public Global() {
EndRequest += (sender, e) => {
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
};
}
這是配置線程安全的?以前我使用自定義IActionInvoker
將相關性注入同一個過濾器。這工作正常,直到MVC 3 RC2,當我開始遇到上述問題時,這就是爲什麼我想我會嘗試使用過濾器提供程序。
任何幫助,將不勝感激。
我使用NHibernate的3 RC和StructureMap的最新版本
更新:
下面是我的DependencyResolver
和FilterAttributeFilterProvider
實現:
public class StructureMapDependencyResolver : IDependencyResolver {
private readonly IContainer container;
public StructureMapDependencyResolver(IContainer container) {
this.container = container;
}
public object GetService(Type serviceType) {
var instance = container.TryGetInstance(serviceType);
if (instance==null && !serviceType.IsAbstract){
instance = AddTypeAndTryGetInstance(serviceType);
}
return instance;
}
private object AddTypeAndTryGetInstance(Type serviceType) {
container.Configure(c=>c.AddType(serviceType,serviceType));
return container.TryGetInstance(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType) {
return container.GetAllInstances(serviceType).Cast<object>();
}
}
public class StructureMapFilterAttributeFilterProvider : FilterAttributeFilterProvider
{
private readonly IContainer container;
public StructureMapFilterAttributeFilterProvider(IContainer container) {
this.container = container;
}
protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
return BuildUp(base.GetControllerAttributes(controllerContext, actionDescriptor));
}
protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
return BuildUp(base.GetActionAttributes(controllerContext, actionDescriptor));
}
private IEnumerable<FilterAttribute> BuildUp(IEnumerable<FilterAttribute> attributes) {
foreach (var attr in attributes)
container.BuildUp(attr);
return attributes;
}
}
我在找一個類似的問題。 – Craig 2010-12-17 03:46:22