c# - .net mvc async/await 的 DI/IoC

标签 c# .net asp.net-mvc asynchronous simple-injector

我正在使用 Simple Injector作为我的 .Net MVC 项目的 IoC 容器。这是我注册服务的方式。

SimpleInjectorInitializer.cs

 public static void Initialize() {
    var container = new Container();

    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();  
    //container.Options.DefaultScopedLifestyle = new ExecutionContextScopeLifestyle(); // replace last line with this for async/await

    InitializeContainer(container);
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
    container.Verify();
    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}

private static void InitializeContainer(Container container) {
    container.Register<MyDbContext>(Lifestyle.Scoped);
    container.Register(typeof(IUnitOfWork<>), typeof(UnitOfWork<>), Lifestyle.Scoped);
    container.Register(typeof(IRepository<>), typeof(Repository<>), Lifestyle.Scoped);
    container.Register<ICustomerService, CustomerService>(Lifestyle.Scoped);

    //what does this do by the way?
    //using (container.BeginExecutionContextScope()) {
    //}
}

客户 Controller

public interface ICustomerService : IService<Customer> {}

public class CustomerService : BaseService<Customer, MyDbContext>, ICustomerService {
    public CustomerService(IUnitOfWork<MyDbContext> unitOfWork) : base(unitOfWork) {}
    // do stuff
}

public class CustomerController : Controller {
    private readonly ICustomerService _service;

    public CustomerController(ICustomerService service) {
        _service = service;
    }

    public ActionResult Index() {
        var foo = _service.GetById(112); // works
        // do stuff
        return View();
    }

    public async Task<int> Foo() { // error out on calling this method
        var foo = await _service.GetByIdAsync(112); 
        return foo.SomeId;
    }
}

我的问题是每当我使用 async/await 时,ioc 都会失败。然后我看了看它的documentation , 它有一个不同的 LifeStyle对于异步方法。所以我改变了 DefaultScopeLifeStyleExecutionContextScopeLifestyle() ,它出错了

The ICustomerService is registered as 'Execution Context Scope' lifestyle, but the instance is requested outside the context of a Execution Context Scope.

我是否需要为使用 asyn/await 和同步方法实现混合生活方式?还是我的设计有问题?

错误详情(带有 WebRequestLifestyle )

The asynchronous action method 'foo' returns a Task, which cannot be executed synchronously.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: The asynchronous action method 'foo' returns a Task, which cannot be executed synchronously.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[InvalidOperationException: The asynchronous action method 'foo' returns a Task, which cannot be executed synchronously.] System.Web.Mvc.Async.TaskAsyncActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +119 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +27 System.Web.Mvc.<>c__DisplayClass15.b__12() +56 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +256 System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +22 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary2 parameters) +190 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +522 NotFoundMvc.ActionInvokerWrapper.InvokeActionWith404Catch(ControllerContext controllerContext, String actionName) +32 NotFoundMvc.ActionInvokerWrapper.InvokeAction(ControllerContext controllerContext, String actionName) +16 System.Web.Mvc.<>c__DisplayClass22.<BeginExecuteCore>b__1e() +23 System.Web.Mvc.Async.AsyncResultWrapper.<.cctor>b__0(IAsyncResult asyncResult, Action action) +15 System.Web.Mvc.Async.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult) +16 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +22 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9765121 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

编辑 我已经确认这不是 Simple Injector 问题,它确实是 this .我试图清理解决方案,删除 bin 文件夹中的 dll,但仍然没有遇到同样的错误。但是,我将 Controller 更改为 ApiController,asyn 运行良好。

最佳答案

据我所知,这个问题与 Simple Injector 及其范围无关;如果您围绕 Web 请求包装执行上下文范围(您可以通过 Hook request_start 和 request_end 事件来完成),您将面临同样的问题。

在 Stackoverflow 和其他互联网上有几个关于此的问题,您应该看看,例如 this q/a .

关于c# - .net mvc async/await 的 DI/IoC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42259821/

相关文章:

c# - Entity Framework - 为导航属性指定继承类型的查询

c# - 如何将 XML 文件转换为数据库?

.net - XSLT 自闭合标签问题

javascript - 如何使用 Kendo Grid 组合行模板和详细信息模板

c# - 多个资源的 Monitor.TryEnter

c# - 如何将数据从表单发送到类?

C# 正则表达式精确长度

.net - GraphSharp .Net 图形布局引擎

javascript - 将选定的行值发送到 Controller MVC 时出现问题

c# - Asp.net mvc Url.Action 使用可为空参数重定向 Controller