2015-08-10 34 views
5

Castle Windsor'u kullanan bir MVC5 uygulamasına sahibim (http://www.artisancode.co.uk/2014/04/integrating-windsor-castle-mvc/). Son zamanlarda bir Async yöntemi bir MVC Controller eklemeye çalıştım. Bunu yaptığımda aşağıdaki hata iletisini alırsınız:Kale Windsor ile Async MVC Aksiyonu

Eşzamansız eylem yöntemi 'sınama', eşzamanlı olarak yürütülemeyen bir Görev döndürür.

VS'de yeni bir MVC uygulaması oluşturdum ve hatayı almadım, bu yüzden Castle Windsor yapılandırmasından bir şey bıraktığımı tahmin ediyorum. Ancak nereden başlayacağımı bilmiyorum ve yardımcı olduğunda herhangi bir makale bulamadım. koduyla

Güncellenmesi soru:

CastleWindsorActionInvoker.cs

public class CastleWindsorActionInvoker : ControllerActionInvoker 
    { 
     private readonly IKernel kernel; 

     public CastleWindsorActionInvoker(IKernel kernel) 
     { 
      this.kernel = kernel; 
     } 

     protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters) 
     { 
      foreach(IActionFilter filter in filters) 
      { 
       kernel.InjectProperties(null, filter); 
      } 

      return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters); 
     } 

     protected override AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList<IAuthorizationFilter> filters, ActionDescriptor actionDescriptor) 
     { 
      foreach(IAuthorizationFilter filter in filters) 
      { 
       Type type = filter.GetType(); 

       IEnumerable<INamedInstanceAttribute> namedInstanceAttributes = type.GetCustomAttributes(typeof(INamedInstanceAttribute), false) as IEnumerable<INamedInstanceAttribute>; 

       if(namedInstanceAttributes != null) 
       { 
        this.kernel.InjectProperties(namedInstanceAttributes, filter); 
       } 
       else 
       { 
        this.kernel.InjectProperties(null, filter); 
       } 
      } 

      return base.InvokeAuthorizationFilters(controllerContext, filters, actionDescriptor); 
     } 
    } 

WindsorDependencyMvcResolver.cs

public class WindsorDependencyMvcResolver : System.Web.Mvc.IDependencyResolver 
    { 
     public IWindsorContainer container { get; protected set; } 

     public WindsorDependencyMvcResolver(IWindsorContainer container) 
     { 
      if(container == null) 
      { 
       throw new ArgumentNullException("container"); 
      } 

      this.container = container; 
     } 

     public object GetService(Type serviceType) 
     { 
      try 
      { 
       return container.Resolve(serviceType); 
      } 
      catch(ComponentNotFoundException) 
      { 
       return null; 
      } 
     } 

     public IEnumerable<object> GetServices(Type serviceType) 
     { 
      return container.ResolveAll(serviceType).Cast<object>(); 
     } 
    } 

CastleWindsorMvcFactory .cs

public class CastleWindsorMvcFactory : DefaultControllerFactory 
    { 
     private readonly IKernel kernel; 

     public CastleWindsorMvcFactory(IKernel kernel) 
     { 
      this.kernel = kernel; 
     } 

     protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
     { 
      if(controllerType == null) 
      { 
       throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path)); 
      } 

      Controller controller = (Controller)kernel.Resolve(controllerType); 

      if(controller != null) 
      { 
       controller.ActionInvoker = kernel.Resolve<IActionInvoker>(); 
      } 

      return controller; 
     } 

     public override void ReleaseController(IController controller) 
     { 
      kernel.ReleaseComponent(controller); 
     } 
    } 

Global.asax

ControllerBuilder.Current.SetControllerFactory(new CastleWindsorMvcFactory(container.Kernel)); 

DependencyResolver.SetResolver(new WindsorDependencyMvcResolver(container)); 

MVC Eylem

public async Task<ActionResult> Index() 
     { 
      return View(); 
     } 
+0

Bize kodunuzu göstererek başlayın. –

+0

Bu eylem başka bir görünümde Html.Action yöntemiyle mi çağrılıyor? –

+0

Sadece bir test yöntemidir, bir tarayıcıda URL'yi girerek doğrudan denir – markpirvine

cevap

2

ve bu article geldi: this action gayet giderir, bu yükleyiciyi kullanma

public class ControllersInstaller : IWindsorInstaller 
{ 
    public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
     container.Register(Classes.FromThisAssembly() 
      .BasedOn<IController>() 
      .LifestyleTransient()); 

     container.Register(Classes.FromThisAssembly() 
      .BasedOn<IHttpController>() 
      .LifestyleTransient()); 
    } 
} 

: Normalde Transient, like so kullanın. Buna dayanarak, CastleWindsorActionInvoker'imi AsyncControllerActionInvoker'den devraldım ve async eylemimi çalıştırabildim.

Tüm önerileriniz için teşekkürler!

1

Yasal Uyarı: Aşağıdaki bağlantılar Oluşturduğum bir sample Github project içindir.

Bu makalede, denetleyicileriniz için yanlış bir yaşam tarzı önerdiğinden şüpheleniyorum. Ben başka bir şey üzerinde çalışıyordu

public async Task<ActionResult> Login(Models.LoginFormModel model, string returnUrl = "") 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      /* ... more code ... */ 
     } 
    } 
    catch (Exception ex) 
    { 
     HandleException(ex); 
    } 

    // If we got this far, something failed; redisplay form 
    return View(model); 
} 
İlgili konular