获取 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 解决方案后,我能够让它工作