获取 ninject 以处理资源 InRequestScope
Getting ninject to dispose of resources InRequestScope
我有一个正在处理的项目,我正在尝试将 ninject 集成到其中。我设置它的方式是我有几个服务 classes 继承自两个相似的基础 classes AbstractService 和 AbstractReadableService,通过我的工作单元它们可以访问数据层。我想要处理的主要依赖项是由 UnitOfWork 持有的 DataContext,后者又由 ninject 注入。
我设置所有这些组件的方法是,我将 ServiceFactory 放入控制器,它从 ninject 获取所需的依赖项。然后,每当我需要服务时,我都会使用 GetService 方法,该方法为从 ServiceFactory 的副本中提取的服务设置所需的依赖项,并 returns 准备好使用该服务的副本。但是,当我导航到新页面或执行任何其他操作时,永远不会调用 UnitOfWork 上的 Dispose 方法。
我的想法是,ServiceFactory 及其依赖项将在每次请求时创建,并且每次我设置新请求时,UnitOfWork 都会处理数据库上下文。但是,我没有使用 dispose 方法,而是希望有人能指出我正确的方向。
抽象服务:
AbstractReadableService 持有工作单元。
public abstract class AbstractService : AbstractReadableService
{
/// <summary>
/// Gets the current user id all lowercase at run time
/// </summary>
protected string UserId; //TODO: Change, to a more complete object, ex: We can resolve the employee number at startup time and get all that from an object returned by ICustomPrincipalService
public AbstractService() { }
/// <summary>
/// Constructor for abstract service that we can use to create a new service inside of other services
/// </summary>
/// <param name="user"></param>
/// <param name="unitOfWork"></param>
public AbstractService(ICustomPrincipalService user, IUnitOfWork unitOfWork)
{
if (base._unitOfWork == null || this.UserId == null)
{
this.UserId = user.GetUser();
base._unitOfWork = unitOfWork;
}
}
public void SetDependencies(ICustomPrincipalService user, IUnitOfWork unitOfWork)
{
if (base._unitOfWork == null || this.UserId == null)
{
this.UserId = user.GetUser();
base._unitOfWork = unitOfWork;
}
else
{
// Throw some really nasty error
}
}
}
工作单元class
public class UnitOfWork : IUnitOfWork
{
private DataContext _dataContext;
public UnitOfWork(DataContext dataContext)
{
//Misc
_dataContext = dataContext;
ISomeRepo SomeRepo { get; private set; }
//Repositories
SomeRepo = new SomeRepo(dataContext);
}
public void SaveChanges(string userId)
{
RecordAuditProperties(userId);
_epmsContext.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
_dataContext.Dispose();
}
}
disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
服务工厂
public class ServiceFactory : IServiceFactory
{
private IUnitOfWork _unitOfWork;
private ICustomPrincipalService _userInfo;
private IEmployeeCredentialService employeeCredentials;
public ServiceFactory(IUnitOfWork unitOfWork, ICustomPrincipalService userInfo, IEmployeeCredentialService employeeCredentials)
{
_unitOfWork = unitOfWork;
_userInfo = userInfo;
}
public T GetService<T>() where T : AbstractService, new()
{
T svc = new T();
svc.SetDependencies(_userInfo, _unitOfWork);
return svc;
}
public T GetReadOnlyService<T>() where T : AbstractReadableService, new()
{
T svc = new T();
svc.SetDependencies(_unitOfWork);
return svc;
}
}
Ninject 绑定:
private void AddBindings()
{
// Binding context to ensure only one context is used in the lifetime of the request
kernel.Bind<DataContext>().ToSelf().InRequestScope();
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
//Deals with pulling the current HTTP context user id into the services
kernel.Bind<ICustomPrincipalService>().To<CustomPrincipalService>().InRequestScope();
kernel.Bind<IHttpContextFactory>().To<HttpContextFactory>().InRequestScope();
kernel.Bind<IEmployeeCredentialService>().To<EmployeeCredentialService>().InRequestScope();
//Disposible dependencies are passed here
kernel.Bind<IServiceFactory>().To<ServiceFactory>().InRequestScope();
}
一切都是正确的,在我安装来自 nuget
的 Ninject MVC4 解决方案后,我能够让它工作
我有一个正在处理的项目,我正在尝试将 ninject 集成到其中。我设置它的方式是我有几个服务 classes 继承自两个相似的基础 classes AbstractService 和 AbstractReadableService,通过我的工作单元它们可以访问数据层。我想要处理的主要依赖项是由 UnitOfWork 持有的 DataContext,后者又由 ninject 注入。
我设置所有这些组件的方法是,我将 ServiceFactory 放入控制器,它从 ninject 获取所需的依赖项。然后,每当我需要服务时,我都会使用 GetService 方法,该方法为从 ServiceFactory 的副本中提取的服务设置所需的依赖项,并 returns 准备好使用该服务的副本。但是,当我导航到新页面或执行任何其他操作时,永远不会调用 UnitOfWork 上的 Dispose 方法。
我的想法是,ServiceFactory 及其依赖项将在每次请求时创建,并且每次我设置新请求时,UnitOfWork 都会处理数据库上下文。但是,我没有使用 dispose 方法,而是希望有人能指出我正确的方向。
抽象服务:
AbstractReadableService 持有工作单元。
public abstract class AbstractService : AbstractReadableService
{
/// <summary>
/// Gets the current user id all lowercase at run time
/// </summary>
protected string UserId; //TODO: Change, to a more complete object, ex: We can resolve the employee number at startup time and get all that from an object returned by ICustomPrincipalService
public AbstractService() { }
/// <summary>
/// Constructor for abstract service that we can use to create a new service inside of other services
/// </summary>
/// <param name="user"></param>
/// <param name="unitOfWork"></param>
public AbstractService(ICustomPrincipalService user, IUnitOfWork unitOfWork)
{
if (base._unitOfWork == null || this.UserId == null)
{
this.UserId = user.GetUser();
base._unitOfWork = unitOfWork;
}
}
public void SetDependencies(ICustomPrincipalService user, IUnitOfWork unitOfWork)
{
if (base._unitOfWork == null || this.UserId == null)
{
this.UserId = user.GetUser();
base._unitOfWork = unitOfWork;
}
else
{
// Throw some really nasty error
}
}
}
工作单元class
public class UnitOfWork : IUnitOfWork
{
private DataContext _dataContext;
public UnitOfWork(DataContext dataContext)
{
//Misc
_dataContext = dataContext;
ISomeRepo SomeRepo { get; private set; }
//Repositories
SomeRepo = new SomeRepo(dataContext);
}
public void SaveChanges(string userId)
{
RecordAuditProperties(userId);
_epmsContext.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
_dataContext.Dispose();
}
}
disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
服务工厂
public class ServiceFactory : IServiceFactory
{
private IUnitOfWork _unitOfWork;
private ICustomPrincipalService _userInfo;
private IEmployeeCredentialService employeeCredentials;
public ServiceFactory(IUnitOfWork unitOfWork, ICustomPrincipalService userInfo, IEmployeeCredentialService employeeCredentials)
{
_unitOfWork = unitOfWork;
_userInfo = userInfo;
}
public T GetService<T>() where T : AbstractService, new()
{
T svc = new T();
svc.SetDependencies(_userInfo, _unitOfWork);
return svc;
}
public T GetReadOnlyService<T>() where T : AbstractReadableService, new()
{
T svc = new T();
svc.SetDependencies(_unitOfWork);
return svc;
}
}
Ninject 绑定:
private void AddBindings()
{
// Binding context to ensure only one context is used in the lifetime of the request
kernel.Bind<DataContext>().ToSelf().InRequestScope();
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
//Deals with pulling the current HTTP context user id into the services
kernel.Bind<ICustomPrincipalService>().To<CustomPrincipalService>().InRequestScope();
kernel.Bind<IHttpContextFactory>().To<HttpContextFactory>().InRequestScope();
kernel.Bind<IEmployeeCredentialService>().To<EmployeeCredentialService>().InRequestScope();
//Disposible dependencies are passed here
kernel.Bind<IServiceFactory>().To<ServiceFactory>().InRequestScope();
}
一切都是正确的,在我安装来自 nuget
的 Ninject MVC4 解决方案后,我能够让它工作