我是否正确地使用AutoFac注册了ObjectContext



我有一个windows服务,我想确保我的EF ObjectContext在每次运行之间都被处理掉。服务每次执行时运行的时间都更长。ObjectContext似乎在不断增长。我的ObjectContext应该以不同的方式注册,还是我做错了什么?

概述我正在做的事情。

  • 我用的是Quartz。NET来安排我的服务
  • 我正在使用Atlas配置和设置我的windows服务
  • 我正在使用Autofac作为我的IoC
  • 我使用实体框架作为我的数据模型

代码演练:

  • 因此,该程序通过使用Atlas注册服务来启动
  • Atlas将注册我的autofac注册,这些注册位于模块MyModule中
  • MyModule在InstancePerLifetimeScope中注册ObjectContext(这是正确的作用域吗?),然后它将有一个我的自定义UnitOfWork实例作为InstancePerLifetimeScope(这是合适的作用域?)
  • MyService由Atlas托管,Atlas注入Quartz调度器和AutofacJobListener属性,并在服务启动时每5分钟调度一次作业(MyJob)
  • MyJob,它从AutofacJobListener获得注入其中的ObjectContext属性实例。这份工作调用数据库并为我获取我的东西

当作业运行时,它每次运行都会调用并获取我的东西,这需要更长的时间(例如:第一次运行2分钟,第二次运行服务4分钟,下一次运行6分钟,下次运行8分钟,依此类推)。我的ObjectContext似乎一次比一次大。它提取的数据没有改变,仍然是相同的行数和列数。所以我认为我的注册是错误的,是这样吗?如果没有,你能看到我做的事情有问题吗?

程序

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main(string[] args)
    {
        var configuration =
            Host.Configure<MyService>(c =>
            {
                c.AllowMultipleInstances();
                c.WithRegistrations(b => b.RegisterModule(new MyModule()));
            }, args);
        Host.Start(configuration);
    }
}

模块

public class MyModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        LoadQuartz(builder);
        LoadServices(builder);
        LoadInfrastructure(builder);
    }
    private void LoadInfrastructure(ContainerBuilder builder)
    {
        builder.Register(c => new ObjectContext())
                .As<IObjectContext>()
                .InstancePerLifetimeScope();
        builder.Register(c => new UnitOfWork(c.Resolve<IObjectContext>()))
            .As<ISession>().As<IObjectContextProvider>()
            .InstancePerLifetimeScope();
    }
    private void LoadQuartz(ContainerBuilder builder)
    {
        builder.Register(c => new StdSchedulerFactory().GetScheduler()).As<IScheduler>().InstancePerLifetimeScope();
        builder.Register(c => new AutofacJobListener(c)).As<IJobListener>();
    }
    private void LoadServices(ContainerBuilder builder)
    {
        builder.RegisterType<MyService>().As<IAmAHostedProcess>().PropertiesAutowired();
    }
}

AutofacJobListener

public class AutofacJobListener : IJobListener
{
    private readonly IComponentContext _container;
    public AutofacJobListener(IComponentContext container)
    {
        _container = container;
    }
    public void JobToBeExecuted(JobExecutionContext context)
    {
        _container.InjectUnsetProperties(context.JobInstance);
    }
    public void JobExecutionVetoed(JobExecutionContext context)
    {
        /*noop*/
    }
    public void JobWasExecuted(JobExecutionContext context, JobExecutionException jobException)
    {
        /*noop*/
    }
    public string Name
    {
        get { return "AutofacInjectionJobListener"; }
    }
}

我的服务

public class MyService : IAmAHostedProcess
{
    public IScheduler Scheduler { get; set; }
    public IJobListener AutofacJobListener { get; set; }
    #region Implementation of IAmAHostedProcess
    public void Start()
    {
        var trigger = TriggerUtils.MakeMinutelyTrigger(5);
        trigger.Name = @"Job Trigger";
        Scheduler.ScheduleJob(new JobDetail("Job", null, typeof(MyJob)), trigger);
        Scheduler.AddGlobalJobListener(AutofacJobListener);
        Scheduler.Start();
    }
    public void Stop()
    {
        Scheduler.Shutdown();
    }
    public void Resume()
    {
    }
    public void Pause()
    {
    }
    #endregion
}

我的工作

public class MyJob : IJob
{
    public IObjectContext ObjectContext { get; set; }
    public void Execute(JobExecutionContext context)
    {
        var myStuff = ObjectContext.GetIQueryable<Stuff>();
    }
}

您正确地注册了它,但您没有在生存期范围内使用它,因此它不会被处理,因为从技术上讲,您的生存期范围就是应用程序的生存期。

Atlas注册所有内容并在应用程序的生存期范围内运行,因此,如果只解析实例,而不创建生存期范围,则会在应用程序生存期的范围内解析实例。在windows应用程序中,生命期范围并不像在web应用程序中那样预先确定,你必须定义它。在你的情况下,你需要围绕单个作业的执行创建一个生命期范围。

在Executing上的AutofacJobListener中创建一个LifetimeScope,并在Executed上处理它。这将强制在该范围内解析的所有实例(即ObjectContext)的生存期仅在该范围(即作业的执行)的持续时间内存在。

添加类似的内容

_lifetimeScope = container.BeginLifetimeScope();
_lifetimeScope.InjectUnsetProperties(context.JobInstance);

_lifetimeScope.Dispose();

以适当的方法。

相关内容

  • 没有找到相关文章

最新更新