【发布时间】:2017-04-14 03:26:42
【问题描述】:
我有 3 层架构 - asp.net web api、BLL 和 DAL。我使用 Ninject 作为依赖注入器,用于在层之间注入数据库上下文和对象。作为 ORM,我使用实体框架。 db 上下文的注入在 DAL 中处理。因此,每次实例化 BLL 中的某个存储库时,也会创建 db 上下文的新实例。我这样做是这样的:
public class UserRepository : IUserRepository
{
private IChatDbModel _chatDbModel;
public UserRepository(IChatDbModel chatDbModel)
{
this._chatDbModel = chatDbModel;
}
有必要说,可以解决我的问题的 PerWebRequest 在比 web api 更低的层中不可用。只有 web api 层有关于 http 请求生命周期的信息,所以可以使用 Ninject.Web.Common 库。
我的问题是,有没有办法像在这个架构中使用 PerWebRequest 那样共享整个请求的数据库上下文?还是真的有必要为每个新的存储库实例创建新的数据库上下文实例?
编辑
我忘了提到在每一层中我都引用了 Ninject 库,并且我正在为特定层注册映射。 DAL 中的方法如下所示:
public static void Register(IKernel kernel)
{
kernel.Bind<IChatDbModel>().To<ChatDbModel>();
}
在 BLL 中是这样的:
public static void Register(IKernel kernel)
{
kernel.Bind<IUserRepository>().To<UserRepository>();
NinjectDataAccess.Register(kernel);
}
在 API 中看起来像这样,它位于 NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUserLogic>().To<UserLogic>();
NinjectLogic.Register(kernel);
}
所以在每一层中,我不仅要映射它自己的对象,还要调用位于下面的层的注册方法,如果有的话,使用这样的机制,我可以注册每一层的依赖映射而不引用所有层API,我不应该引用除 BLL 之外的任何其他层,所以在我的情况下是 DAL。如果我在 API 层中引用 DAL,则可以定义映射并调用 PerWebRequest,因为我会有对象,但我没有,我认为架构应该避免这种情况,还是我错了?
【问题讨论】:
-
您的问题假设您的 BLL 和 DAL 对 Ninject 以及事物的注册方式一无所知;他们不应该。由于对象已在Composition Root 中注册(在您的情况下位于您的网络项目中),因此将您的
DbContext注册为PerWebRequest应该没有问题。 -
感谢您的回复,实际上我在每一层都定义了依赖映射,所以我在每一层都引用了 Ninject,以避免在 API 中引用 DAL——我认为应该避免建筑学。请检查我的编辑。
-
您不应该在每一层中定义您的 DI 映射。请阅读this related q/a。
标签: c# asp.net dependency-injection dbcontext data-access-layer