繁体   English   中英

如何使用异步任务正确配置简单注入器

[英]How to Properly configure Simple Injector with Async Tasks

我在ASP.NET MVC应用程序中拥有自托管的WebAPI。 我想在执行我的API动作之一时执行一些异步动作。 异步操作具有对DbContext的依赖性以及其他一些依赖性。

以下是我的简单注入器配置。

public class SimpleInjectorIntegrator
{
    private static Container container;

    public static Container Setup()
    {
        container = new Container();
        container.Options.DefaultScopedLifestyle = Lifestyle.CreateHybrid(
            defaultLifestyle: new WebRequestLifestyle(),
            fallbackLifestyle: new AsyncScopedLifestyle());

        container.Register<IBaseRepository<User>, BaseRepository<User>>(Lifestyle.Scoped);
        container.Register<ComputationService>(Lifestyle.Scoped);
        container.Register<ILog, Logger>(Lifestyle.Scoped);

        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
    }

    public static T Get<T>() where T : class
    {
        if (container == null)
            throw new InvalidOperationException("Container hasn't been initialized.");

        return container.GetInstance<T>();
    }
}

Global.asax.cs看起来像这样。

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        var container = SimpleInjectorIntegrator.Setup();
        GlobalConfiguration.Configure(WebApiConfig.Register);

        ...some other code...
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }
}

以下是API控制器。

public class ExperimentUploadController : ApiController
{
    private ComputationService _service = SimpleInjectorIntegrator.Get<ComputationService>();

    public IHttpActionResult Started(InputModel model)
    {
        ...Do Something...
        var task = Task.Run(() =>
        {
             _service.Do(model.Id);
        });
    }
}

该API取决于ComputationService ,后者使用存储库执行与数据库的连接。 当我尝试从ComputationService访问数据库时,它抛出DbContext被丢弃的情况。

ComputationService代码如下所示:

public class ComputationService 
{
    private IBaseRepository<User> _userRepo = SimpleInjectorIntegrator.Get<User>();

    public void Do(int id) 
    {
        ///throws here
        var user = _userRepo.Get(id);
    }
}

我不确定为什么会这样。

我面临的实际问题是我不希望我的API等待异步操作完成,因此像@John所述处理DbContext。 但是我需要使用SimpleInjector来使用AsyncScopedLifestyle来解决依赖关系,因为我已经在配置中对其进行了配置。

我使用这个Github链接找到了答案。 我所做的是将我的Asynchronous方法包装在Asynchronous范围内,并解决了该范围内的依赖关系,并且它起作用了。

这是更新的代码。

public class ComputationService 
{
    private IBaseRepository<User> _userRepo;

    public void Do(int id) 
    {
        using(AsyncScopedLifestyle.BeginScope(SimpleInjectorIntegrator.Container)) 
        {
            _userRepo = = SimpleInjectorIntegrator.Container.GetInstance<User>();
            var user = _userRepo.Get(id); //works fine.
        }
    }
}

我进行的SimpleInjectorIntegrator一项更改是通过SimpleInjectorIntegrator类中的Property公开Container。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM