asp.net – 如何使用依赖注入将工作单元容器传递到存储库的构造
我正在尝试研究如何在ASP.NET Web应用程序中完成我的Repository模式的实现.
目前,我有一个每个域类的存储库接口,用于定义例如加载和保存该类的实例. 每个存储库接口都由一个执行NHibernate工作的类实现. Castle Windsor根据web.config将类的DI排序到界面中.下面提供了一个实现类的示例: public class StoredWillRepository : IStoredWillRepository { public StoredWill Load(int id) { StoredWill storedWill; using (ISession session = NHibernateSessionFactory.OpenSession()) { storedWill = session.Load<StoredWill>(id); NHibernateUtil.Initialize(storedWill); } return storedWill; } public void Save(StoredWill storedWill) { using (ISession session = NHibernateSessionFactory.OpenSession()) { using (ITransaction transaction = session.BeginTransaction()) { session.SaveOrUpdate(storedWill); transaction.Commit(); } } } } 正如前一个线程所指出的,存储库类需要接受一个工作单元容器(即ISession),而不是在每个方法中实例化它. 我预计工作单元容器将在需要时由每个aspx页面创建(例如,在属性中). 然后,当Windsor为我创建时,如何指定将此工作单元容器实例传递到StoredWillRepository的构造函数中? 或者这种模式完全错了? 再次感谢您的建议. 大卫 解决方法
我有一个基于NHibernate构建的持久性框架,用于一些Web应用程序.它隐藏了IRepository和IRepository< T>之后的NH实现.接口,具有Unity提供的具体实例(因此我理论上可以相当容易地将NHibernate替换为实体框架).
由于Unity没有(或者至少我使用的版本没有)支持传递除了依赖注入本身之外的构造函数参数,因此无法传入现存的NH ISession;但我确实希望UOW中的所有对象共享同一个ISession. 我通过拥有一个控制存储库类来解决这个问题,该类在每个线程的基础上管理对ISession的访问: public static ISession Session { get { lock (_lockObject) { // if a cached session exists,we'll use it if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY)) { return (ISession)PersistenceFrameworkContext.Current.Items[NHibernateRepository.SESSION_KEY]; } else { // must create a new session - note we're not caching the new session here... that's the job of // BeginUnitOfWork(). return _factory.OpenSession(new NHibernateInterceptor()); } } } } 在此示例中,PersistenceFrameworkContext.Current.Items访问IList< object>如果不在Web上下文中,则存储在ThreadStatic中;如果在Web上下文中,则存储在HttpContext.Current.Items中(以避免线程池问题).对属性的第一次调用从存储的工厂实例中实例化ISession,后续调用只是从存储中检索它.锁定会略微降低速度,但不会像锁定appdomain范围的静态ISession实例那样多. 然后我有BeginUnitOfWork和EndUnitOfWork方法来处理UOW – 我特别禁止嵌套的UOW,因为坦率地说它们很难管理. public void BeginUnitOfWork() { lock (_lockObject) { if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY)) EndUnitOfWork(); ISession session = Session; PersistenceFrameworkContext.Current.Items.Add(SESSION_KEY,session); } } public void EndUnitOfWork() { lock (_lockObject) { if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY)) { ISession session = (ISession)PersistenceFrameworkContext.Current.Items[SESSION_KEY]; PersistenceFrameworkContext.Current.Items.Remove(SESSION_KEY); session.Flush(); session.Dispose(); } } } 最后,一对方法提供对特定于域类型的存储库的访问: public IRepository<T> For<T>() where T : PersistentObject<T> { return Container.Resolve<IRepository<T>>(); } public TRepository For<T,TRepository>() where T : PersistentObject<T> where TRepository : IRepository<T> { return Container.Resolve<TRepository>(); } (这里,PersistentObject< T>是提供ID和Equals支持的基类.) 因此,访问给定的存储库就是这种模式 NHibernateRepository.For<MyDomainType>().Save(); 这样就可以使用了 MyDomainType.Repository.Save(); 在给定类型具有专用存储库的情况下(即,需要比从IRepository< T>获得的更多),然后我创建从IRepository< T>派生的接口,这是从我的IRepository< T>继承的扩展实现.实现,并在域类型本身我使用new覆盖静态存储库属性 new public static IUserRepository Repository { get { return MyApplication.Repository.For<User,IUserRepository>(); } } (MyApplication [在真实产品中被称为不那么笨拙]是一个Facade类,负责通过Unity提供Repository实例,因此您不依赖于域类中特定的NHibernate存储库实现.) 这为我提供了通过Unity实现存储库实现的完全可插拔性,可以轻松访问代码中的存储库而无需跳过箍,以及透明的每线程ISession管理. 代码不仅仅是上面的代码(我已经简化了示例代码),但是你得到了一般的想法. MyApplication.Repository.BeginUnitOfWork(); User user = User.Repository.FindByEmail("wibble@wobble.com"); user.FirstName = "Joe"; // change something user.LastName = "Bloggs"; // you *can* call User.Repository.Save(user),but you don't need to,because... MyApplication.Repository.EndUnitOfWork(); // ...causes session flush which saves the changes automatically 在我的Web应用程序中,我有每个请求的会话,因此分别在BeginRequest和EndRequest中调用BeginUnitOfWork和EndUnitOfWork. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – 如何在不创建多个动作结果的情况下将字符串
- asp.net – 在aspnet核心1应用程序的逻辑层中获取ClaimsPri
- 在ASP.NET Membership provider中将电子邮件地址设置为用户
- asp.net-mvc-3 – 实体框架代码优先:“ObjectStateManager
- asp.net – 过滤掉字符串中的锚标记
- ASP.NET MVC 4 AJAX提交表单不工作
- asp.net-mvc – 确保每个控制器方法都有一个ValidateAntiFo
- asp.net – 从AuthorizeAttribute Filter获取cookie
- asp.net-mvc – ASP.NET MVC可配置验证
- entity-framework – EF codefirst如何知道为哪个模型类创建
- asp.net – 具有一个无效的SelectedValue,因为它
- asp.net-mvc – Olark免费替代品
- asp.net-mvc – 使用NHibernate和Autofac管理多个
- asp.net-mvc – 如何将Bootstrap下拉式样应用于A
- asp.net – .NET“代码块块”?
- asp.net-mvc – 如何在ASP.NET MVC中阻止JSON序列
- asp.net-mvc-3 – 在下拉列表中更改值时的页面重
- asp.net – 在PostBack期间Recaptcha消失
- asp.net-mvc – System.Web.MVC.UpdateModel可以
- asp.net-mvc – ASP.NET MVC 3发布日期?