gpt4 book ai didi

c# - 应用程序设计 : NH-session management, 通用存储库,ASP.NET MVC

转载 作者:太空宇宙 更新时间:2023-11-03 22:04:18 25 4
gpt4 key购买 nike

定义了一个领域模型后,我想弄清楚如何完成剩下的工作。


数据访问层

我之前读过,没有必要在 ISession 上编写自己的 UnitOfWork 实现(虽然我找到了很多关于如何做得很好的信息)。所以我很困惑..我有这样的存储库界面:

public interface IRepository<T> where T: AbstractEntity<T>, IAggregateRoot
{
T Get(Guid id);
IQueryable<T> Get(Expression<Func<T, Boolean>> predicate);
IQueryable<T> Get();
T Load(Guid id);
void Add(T entity);
void Remove(T entity);
void Remove(Guid id);
void Update(T entity);
void Update(Guid id);
}

具体实现中有两种选择:

选项A

是通过构造函数注入(inject) ISessionFactory 并具有类似于:

public class Repository<T> : IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
private ISessionFactory sessionFactory;

public Repository(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
public T Get(Guid id)
{
using(var session = sessionFactory.OpenSession())
{
return session.Get<T>(id);
}
}
}

选项 B

就是使用NHibernateHelper

using(var session = NHibernateHelper.GetCurrentSession())
{
return session.Get<T>(id);
}

NHibernateHelper 在哪里

internal sealed class NHibernateHelper
{
private const string CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory sessionFactory;

static NHibernateHelper()
{
sessionFactory = new Configuration().Configure().BuildSessionFactory();
}

public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;

if(currentSession == null)
{
currentSession = sessionFactory.OpenSession();
context.Items[CurrentSessionKey] = currentSession;
}

return currentSession;
}

public static void CloseSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;

if(currentSession == null)
{
return;
}

currentSession.Close();
context.Items.Remove(CurrentSessionKey);
}

public static void CloseSessionFactory()
{
if(sessionFactory != null)
{
sessionFactory.Close();
}
}
}

首选什么选项?

为什么(除了注入(inject))?

如果我使用选项 A,我应该在哪里放置 ISessionFactory 的配置?

它应该放在 ASP.NET MVC 项目中的某个地方吗?怎么办?

感谢您阅读怪物问题!感谢您的指导!

最佳答案

如何使用 mvc 处理注入(inject)依赖关系在某种程度上是特定于版本的,但它总是有助于使用真正的依赖注入(inject) (DI) 容器。无论您如何分割它,此解决方案都需要您将 ISession 注入(inject)存储库而不是 ISessionFactory。这允许您的 DI 容器正确管理 session 的生命周期。

假设您正在使用 Asp.Net MVC 3 并且还没有到特定 DI 容器的附件,请启动您的 Nuget控制台和类型:

install-package Ninject.MVC3

这将开始,下载 Ninject(这是一个 DI 容器)并配置您的 mvc 应用程序以使用它。它还将创建一个文件 ~/App_Start/NinjectMVC3.cs,您可以在其中配置依赖项。

private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ISessionFactory>()
.ToMethod(c => new Configuration().Configure().BuildSessionFactory())
.InSingletonScope();

kernel.Bind<ISession>()
.ToMethod((ctx) => ctx.Kernel.Get<ISessionFactory>().OpenSession())
.InRequestScope();

kernel.Bind<IRepository<>>().To<Repository<>>();
}

第一个语句告诉 ninject,当某些东西需要 ISessionFactory 时,它应该懒惰地初始化 NHibernate 并创建一个。然后,该 session 工厂将作为应用程序范围内的单例在应用程序的生命周期内保持。

第二条语句告诉 ninject,当某些东西需要 ISession 时,它应该获取 ISessionFactory 的实例并调用 OpenSession()。这个 Session 然后在请求的范围内被重用,并在请求结束时被销毁。

第三条语句告诉 ninject,当某些东西需要任何类型的 IRepository 时,它应该使用它内置的逻辑来解决依赖关系,只是新建一个。

从这里您可以编写如下代码,一切都应该正常工作。

public class WidgetController : Controller
{
private readonly IRepository<Widget> _repository;
public WidgetController(IRepository<Widget> repository)
{
_repository = repository;
}
}

关于存储库,我想向您推荐一篇优秀的博文 Repository is the new Singleton

关于c# - 应用程序设计 : NH-session management, 通用存储库,ASP.NET MVC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8987103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com