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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Azure Web作业中的调用范围绑定中配置Ninject?相关的知识,希望对你有一定的参考价值。

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

//注册上下文

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

问题来自My Previous Post之一

我正在发布Step By Step Solution

(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)Ninject Bindings

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);
            }

        } 

以上是关于如何在Azure Web作业中的调用范围绑定中配置Ninject?的主要内容,如果未能解决你的问题,请参考以下文章

使用Azure Web作业配置应用程序洞察

如何使用 MSI 而不是 Service Principal 来调用部署在 Azure 上的 Authenticate web api

Azure Web 作业总是失败

当它绑定到调用函数中的 const 引用时,它的返回值的生命周期如何扩展到调用函数的范围?

当它被绑定到调用函数中的const引用时,它的返回值的生命周期如何扩展到调用函数的范围?

流分析作业的 Azure 函数绑定类型?