在 Ninject 中处理
Disposing in Ninject
我对 DI 使用 Ninject,它为每个请求创建 DbContext(所有服务都创建一个)并且我通常为每个请求调用几个服务方法(所以我无法在调用第一个服务方法后处理 DbContext ).
问题是,我应该使 WallService 或 WallManager(以及其他服务和管理器)成为 IDisposable 以及创建什么 Dispose 逻辑?
我的业务逻辑层
namespace MySite.BLL.Services
{
public class WallService
{
WallManager wallManager;
public WallService(MybContext db)
{
wallManager = new WallManager(db);
}
}
}
我的数据访问层
namespace MySite.DAL.Repositories
{
public class WallManager
{
MyDbContext db;
public WallManager(MyDbContext db)
{
this.db = db;
}
}
}
NinjectWebCommon.cs
kernel.Bind<MyDbContext>().ToSelf().InRequestScope().WithConstructorArgument<string>("MyMsSqlString");
kernel.Bind<WallService>().ToSelf().InRequestScope();
MyBaseController.cs
public class MyBaseController : Controller
{
[Inject]
public WallService WallService { get; set; }
// Other Services ..
}
(这与其说是答案,不如说是扩展评论)
我很确定你不需要这样做 - 不仅你不需要需要而且你真的不应该 在这种情况下。
事实是,您不是自己创建 DbContext
实例 - 您是将此责任委托给 IOC 库;在这方面,参考仅 "passing through" 所以 none 的 类 拥有它,不应做任何可能破坏它的事情。
此外,DbContext
是一个托管对象,因此您无论如何都不需要 Dispose
。
,虽然它没有直接解决你的问题,因此我没有标记为重复
关于您的代码,我注意到一件事。
您正在注入 DbContext
,然后使用它创建一个 WallManager
实例。这有点违背了依赖注入的目的。为什么不直接将 WallManager
注入 WallService
?
即
public class WallService
{
readonly WallManager _wallManager;
public WallService(WallManager manager)
{
if (manager==null){
throw new ArgumentNullException("manager");
}
_wallManager = manager;
}
}
Ninject
(或任何其他 IOC 库)在确定需要创建 DbContext
并将其注入 manager
依赖项时没有问题,一旦您注册了WallManager
用它打字;这里的想法是你注册所有可能的依赖类型,然后库为你构建对象图。
这样你就不必在 WallService
中直接依赖 DbContext
...我猜你只是为了创建 WallManager
无论如何 - 如果您 也 在 WallService
中使用 DbContext
我建议您再看看设计,因为您应该将数据访问限制在一层。
我对 DI 使用 Ninject,它为每个请求创建 DbContext(所有服务都创建一个)并且我通常为每个请求调用几个服务方法(所以我无法在调用第一个服务方法后处理 DbContext ).
问题是,我应该使 WallService 或 WallManager(以及其他服务和管理器)成为 IDisposable 以及创建什么 Dispose 逻辑?
我的业务逻辑层
namespace MySite.BLL.Services
{
public class WallService
{
WallManager wallManager;
public WallService(MybContext db)
{
wallManager = new WallManager(db);
}
}
}
我的数据访问层
namespace MySite.DAL.Repositories
{
public class WallManager
{
MyDbContext db;
public WallManager(MyDbContext db)
{
this.db = db;
}
}
}
NinjectWebCommon.cs
kernel.Bind<MyDbContext>().ToSelf().InRequestScope().WithConstructorArgument<string>("MyMsSqlString");
kernel.Bind<WallService>().ToSelf().InRequestScope();
MyBaseController.cs
public class MyBaseController : Controller
{
[Inject]
public WallService WallService { get; set; }
// Other Services ..
}
(这与其说是答案,不如说是扩展评论)
我很确定你不需要这样做 - 不仅你不需要需要而且你真的不应该 在这种情况下。
事实是,您不是自己创建 DbContext
实例 - 您是将此责任委托给 IOC 库;在这方面,参考仅 "passing through" 所以 none 的 类 拥有它,不应做任何可能破坏它的事情。
此外,DbContext
是一个托管对象,因此您无论如何都不需要 Dispose
。
关于您的代码,我注意到一件事。
您正在注入 DbContext
,然后使用它创建一个 WallManager
实例。这有点违背了依赖注入的目的。为什么不直接将 WallManager
注入 WallService
?
即
public class WallService
{
readonly WallManager _wallManager;
public WallService(WallManager manager)
{
if (manager==null){
throw new ArgumentNullException("manager");
}
_wallManager = manager;
}
}
Ninject
(或任何其他 IOC 库)在确定需要创建 DbContext
并将其注入 manager
依赖项时没有问题,一旦您注册了WallManager
用它打字;这里的想法是你注册所有可能的依赖类型,然后库为你构建对象图。
这样你就不必在 WallService
中直接依赖 DbContext
...我猜你只是为了创建 WallManager
无论如何 - 如果您 也 在 WallService
中使用 DbContext
我建议您再看看设计,因为您应该将数据访问限制在一层。