依赖注入处理case当HttpContext.Current不存在 [英] Dependency Injection to Handle Case When HttpContext.Current Doesn't Exist

查看:341
本文介绍了依赖注入处理case当HttpContext.Current不存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  container.RegisterType< ISessionFactory>(新ContainerControlledLifetimeManager(),新InjectionFactory(C => {
    返回BuildSessionFactory();
}));
container.RegisterType<&ISession的GT;(新PerRequestLifetimeManager<&ISession的GT;(),新InjectionFactory(C => {
    返回c.Resolve&所述; ISessionFactory方式>()的openSession();
}));

会话工厂(ISessionFactory)生活应用程序的长度。会话(ISession的)生活在ASP.NET请求的长度。我在Application_EndRequest活动还处理了会议。这让我在我的应用程序注入的ISession,它按预期工作。

我现在正在试图建立任务调度到我的应用程序。我已经添加了以下code到Application_Start事件:

  VAR定时器=新System.Timers.Timer(5000);
timer.Elapsed + =(发件人,E)=> {
    VAR线程=新主题(新的ThreadStart(()=> {
        VAR的服务= DependencyResolver.Current.GetService< ISomeService>();        ...
    }));
    thread.Start();
};
timer.Enabled = TRUE;

这应该运行每5秒。 ISomeService的实施注入了的ISession在构造函数中,我不希望改变这个类。当它试图解决的ISession,因为它试图解决它在一个线程,其中HttpContext.Current为null,因此抛出一个异常我的问题就出现了。我不知道我应该如何注册处理这种情况的会议。我倒是AP preciate的帮助。

感谢

下面是我的PerRequestLifetimeManager类柜面它可以帮助:

 公共类PerRequestLifetimeManager< T> :LifetimeManager {
    公众覆盖对象的GetValue(){
        返回HttpContext.Current.Items [typeof运算(T).AssemblyQualifiedName]
    }    公共覆盖无效RemoveValue(){
        HttpContext.Current.Items.Remove(typeof运算(T).AssemblyQualifiedName);
    }    公共覆盖无效的SetValue(对象为newValue){
        HttpContext.Current.Items [typeof运算(T).AssemblyQualifiedName] =为newValue;
    }
}


解决方案

解决该ISessionFactory和管理会话的寿命你自己。

  VAR定时器=新System.Timers.Timer(5000);
timer.Elapsed + =(发件人,E)=> {
VAR线程=新主题(新的ThreadStart(()=> {
    VAR的服务= DependencyResolver.Current.GetService< ISessionFactory>();
    使用(VAR会话= service.OpenSession())
    {
        //做一些会话
    }    ...
}));
thread.Start();
};
timer.Enabled = TRUE;

编辑:
团结有,可以有不同的配置多个容器实例的功能。这样,你可以配置为服务

不同lifetimemanager

I have an ASP.NET MVC application and in my Application_Start event I have the following code:

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

The session factory (ISessionFactory) lives for the length of the application. The session (ISession) lives for the length of the ASP.NET request. I also dispose the session in the Application_EndRequest event. This allows me to inject the ISession throughout my application and it works as expected.

I'm now trying to build task scheduling into my application. I have added the following code into the Application_Start event:

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;

This should run every 5 seconds. The implementation of ISomeService injects the ISession in the constructor and I don't wish to change this class. My issue arises when it tries to resolve ISession as it tries to resolve it in a thread where HttpContext.Current is null and therefore an exception is thrown. I was wondering how I should register the session to handle this scenario. I'd appreciate the help.

Thanks

Here's my PerRequestLifetimeManager class incase it helps:

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

解决方案

Resolve the ISessionFactory and manage the lifetime of the session yourself.

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;

Edit: Unity has a feature with multiple container instances that can have different configuration. That way you can have a different lifetimemanager configured for the "service"

这篇关于依赖注入处理case当HttpContext.Current不存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆