我有一个Windows服务,我想确保我的EF ObjectContext在每次运行之间被处置。每次执行服务时都会运行更长时间。看起来ObjectContext不断增长。我的ObjectContext应该以不同的方式注册还是我做错了什么?我正确使用AutoFac注册ObjectContext吗?
我在做什么的概述。
- 我使用Quartz.NET来安排我的服务
- 我使用Atlas配置和安装我的窗口服务
- 我用Autofac作为我的IoC
- 我使用实体框架因为我的数据模型
Walkthru代码:
- 因此,程序通过使用Atlas注册服务开始。
- Atlas将注册在被安置在模块MyModule的我autofac注册
- MyModule的寄存器中的ObjectContext在InstancePerLifetimeScope(这是正确的范围是什么?),那么就会有一次,我的自定义的UnitOfWork作为InstancePerLifetimeScope的情况下(这是该正确的范围?)。
- MyService由Atlas托管,Atlas获取Quartz调度程序和AutofacJobListener属性,并在服务启动时安排作业(MyJob)每5分钟运行一次。
- MyJob获取从AutofacJobListener注入到ObjectContext属性的实例。这项工作叫出数据库,让我得到我的东西。
作业运行时它的每一个运行时,它需要更长的时间调出并得到我的东西(例如:5分钟运行,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"; }
}
}
为MyService
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>();
}
}
谢谢正是我一直在寻找,我居然进了一步,并使用阿特拉斯的力量。我改变了我的AutofacJobListener在Atlas.ContainerProvider.Instance则使用的ContainerProvider的BeginLifetimeScope通过() – Mark 2011-06-17 16:04:38