1

我有一个 ASP.NET MVC 应用程序,在我的 Application_Start 事件中我有以下代码:

container.RegisterType<ISessionFactory>(new ContainerControlledLifetimeManager(), new InjectionFactory(c => {
    return BuildSessionFactory();
}));
container.RegisterType<ISession>(new PerRequestLifetimeManager<ISession>(), new InjectionFactory(c => {
    return c.Resolve<ISessionFactory>().OpenSession();
}));

会话工厂 (ISessionFactory) 在应用程序的整个期间都存在。会话 (ISession) 在 ASP.NET 请求期间存在。我还在 Application_EndRequest 事件中处理会话。这使我可以在整个应用程序中注入 ISession,它可以按预期工作。

我现在正在尝试将任务调度构建到我的应用程序中。我已将以下代码添加到 Application_Start 事件中:

var timer = new System.Timers.Timer(5000);
timer.Elapsed += (sender, e) => {
    var thread = new Thread(new ThreadStart(() => {
        var service = DependencyResolver.Current.GetService<ISomeService>();

        ...
    }));
    thread.Start();
};
timer.Enabled = true;

这应该每 5 秒运行一次。ISomeService 的实现在构造函数中注入了 ISession,我不希望更改此类。当它尝试解决 ISession 时出现我的问题,因为它试图在 HttpContext.Current 为空的线程中解决它,因此引发异常。我想知道我应该如何注册会话来处理这种情况。我会很感激帮助。

谢谢

这是我的 PerRequestLifetimeManager 类,因为它有帮助:

public class PerRequestLifetimeManager<T> : LifetimeManager {
    public override object GetValue() {
        return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
    }

    public override void RemoveValue() {
        HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
    }

    public override void SetValue(object newValue) {
        HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
    }
}
4

1 回答 1

1

解析 ISessionFactory 并自己管理会话的生命周期。

var timer = new System.Timers.Timer(5000);
timer.Elapsed += (sender, e) => {
var thread = new Thread(new ThreadStart(() => {
    var service = DependencyResolver.Current.GetService<ISessionFactory>();
    using(var session = service.OpenSession())
    {
        //do something with session
    }

    ...
}));
thread.Start();
};
timer.Enabled = true;

编辑:Unity 具有多个容器实例的功能,这些实例可以具有不同的配置。这样,您可以为“服务”配置不同的生命周期管理器

于 2013-10-30T20:59:08.817 回答