如何在 Azure Web 作业中的调用范围绑定中配置 Ninject?

How to configure Ninject in call scope binding within Azure Web Job?

我在尝试编写 Web 作业调度程序时遇到问题。我正在使用 Ninject 使用 EF 存储库模式的范围绑定。但只有 InSingletonScope() 按预期工作。如何在 RequestScope 或 Call Scope 中配置它?

//注册上下文

    Kernel.Bind<MyDbContext>().ToSelf().InSingletonScope();
    Kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>().InSingletonScope();

问题已从 My Previous Post

之一解决

我正在发布分步解决方案

(1.)NinjectJobActivator

    public class NinjectJobActivator : IJobActivator
    {
        #region Variable Declaration
        private readonly IResolutionRoot _resolutionRoot;
        #endregion

        #region CONSTRUCTOR
        /// <summary>
        /// 
        /// </summary>
        /// <param name="kernel"></param>
       // public NinjectJobActivator(IKernel kernel)
        public NinjectJobActivator(IResolutionRoot resolutionRoot)
        {
            _resolutionRoot = resolutionRoot;
        }
        #endregion


        #region CreateInstance
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T CreateInstance<T>()
        {
            return _resolutionRoot.Get<T>(new CallScopedParameter());
        }
        #endregion
    }

(2) NinjectBindings

using Ninject.Extensions.Conventions;
using Ninject.Extensions.NamedScope;

public class NinjectBindings : NinjectModule
    {
        public override void Load()
        {
            //Register Context
            Kernel.Bind<MyDbContext>().ToSelf()
                  .When(x => x.Parameters.OfType<CallScopedParameter>().Any())
                  .InCallScope();  // For Scheduler

            Kernel.Bind<IUnitOfWork<MyDbContext>>().To<UnitOfWork<MyDbContext>>();

            //Register Repository
            Kernel.Bind(x => x
           .FromAssemblyContaining<MyDbContext>()
           .SelectAllClasses()
           .InheritedFrom(typeof(IRepository<>))
           .BindDefaultInterface());

        }
    }

(3) Program.cs

static void Main()
        {
            using (IKernel kernel = new StandardKernel(new NinjectBindings()))
            {
                var config = new JobHostConfiguration()
                {
                    JobActivator = new NinjectJobActivator(kernel)
                };

                if (config.IsDevelopment)
                {
                    config.UseDevelopmentSettings();
                }

                // Timer Trigger
                config.UseTimers();

                var host = new JobHost(config);
                //// The following code ensures that the WebJob will be running continuously
                host.RunAndBlock();
            }

        }

(4) CallScopedParameter

public sealed class CallScopedParameter : IParameter
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public bool Equals(IParameter other)
        {
            if (other == null)
            {
                return false;
            }

            return other is CallScopedParameter;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public object GetValue(IContext context, ITarget target)
        {
            throw new NotSupportedException("this parameter does not provide a value");
        }

        /// <summary>
        /// 
        /// </summary>
        public string Name
        {
            get { return typeof(CallScopedParameter).Name; }
        }

        /// <summary>
        /// this is very important
        /// </summary>
        public bool ShouldInherit
        {
            get { return true; }
        }
    }

(5) Azure Web 作业函数

public void DoSomething([TimerTrigger("*/30 *  * * * *")] TimerInfo timer, TextWriter log)
        {
            try
            {

                var tempdetails = _sampleRepository.SearchFor(x=> DateTime.UtcNow > x.DateTo);

                foreach (var detail in tempdetails)
                {
                    if (detail.ID == 2)
                    {
                        detail.ID = 5;
                    }
                    _sampleRepository.Update(detail);
                }

                 _unitOfWork.Commit();

            }
            catch (Exception ex)
            {
                log.WriteLine(ex.Message);
            }

        }