简体   繁体   English

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

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

I have self-hosted WebAPI inside my ASP.NET MVC application. 我在ASP.NET MVC应用程序中拥有自托管的WebAPI。 I want to perform some asynchronous action when one of my API action is executed. 我想在执行我的API动作之一时执行一些异步动作。 The asynchronous action has dependency on DbContext along with some other dependencies. 异步操作具有对DbContext的依赖性以及其他一些依赖性。

Following is my Simple Injector configuration. 以下是我的简单注入器配置。

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

The Global.asax.cs looks like this. 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));
    }
}

Below is the API Controller. 以下是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);
        });
    }
}

The API depends on ComputationService which performs connects with database using a repository. 该API取决于ComputationService ,后者使用存储库执行与数据库的连接。 When I am trying to access the database from ComputationService , it throws that DbContext is disposed. 当我尝试从ComputationService访问数据库时,它抛出DbContext被丢弃的情况。

ComputationService code looks like below: ComputationService代码如下所示:

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

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

I am not sure why this is happening. 我不确定为什么会这样。

The actual problem that I was facing was that I do not want my API to wait for the asynchronous operation to complete and hence the DbContext was being disposed as mentioned by @John. 我面临的实际问题是我不希望我的API等待异步操作完成,因此像@John所述处理DbContext。 But I require SimpleInjector to resolve the dependency using AsyncScopedLifestyle as I have configured it in my configuration. 但是我需要使用SimpleInjector来使用AsyncScopedLifestyle来解决依赖关系,因为我已经在配置中对其进行了配置。

I found the answer using this Github link . 我使用这个Github链接找到了答案。 What I did is wrapped my Asynchronous method inside the Asynchronous scope and resolved dependencies in that scope and it worked. 我所做的是将我的Asynchronous方法包装在Asynchronous范围内,并解决了该范围内的依赖关系,并且它起作用了。

Here is the updated code. 这是更新的代码。

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

One more change I have made is to expose the Container via Property in my SimpleInjectorIntegrator class. 我进行的SimpleInjectorIntegrator一项更改是通过SimpleInjectorIntegrator类中的Property公开Container。

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

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