我有一个名为LanguageBase的抽象类。
我还有一个名为Language的派生类(不要担心我为什么这样做 - 有一个有效的用例,但不属于本讨论的范围。)
在我的ASP.Net MVC应用程序中,我有一个控制器,其中一些操作方法将LanguageBase作为参数。在运行时,Autofac必须将其解析为语言。
在Global.asax中,我有以下方法来注册我的类型并创建我的容器:
private void RegisterTypes()
{
var builder = new ContainerBuilder();
//http://autofac.readthedocs.org/en/latest/integration/mvc.html
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
builder.RegisterType<Language>().As<LanguageBase>();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
但是,在运行时,我收到此错误:
&#39; /&#39;中的服务器错误应用
无法创建抽象类。
描述:执行期间发生了未处理的异常 当前的网络请求。请查看堆栈跟踪了解更多信息 有关错误的信息以及它在代码中的起源。
异常详细信息:System.MissingMethodException:无法创建 抽象类。
来源错误:
执行期间生成了未处理的异常 当前的网络请求。有关的来源和位置的信息 可以使用下面的异常堆栈跟踪来识别异常。
堆栈追踪:
[MissingMethodException:无法创建抽象类。]
System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔值 publicOnly,Boolean noCheck,Boolean&amp; canBeCached, RuntimeMethodHandleInternal&安培; ctor,布尔&amp; bNeedSecurityCheck)+0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly,Boolean skipCheckThis,Boolean fillCache,StackCrawlMark&amp; stackMark)+113
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis,Boolean fillCache,StackCrawlMark&amp; stackMark) +206 System.Activator.CreateInstance(Type type,Boolean nonPublic)+83 System.Activator.CreateInstance(Type type)+11 System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType) 197[MissingMethodException:无法创建抽象类。对象类型 &#39; Visia.PartyRoles.Generic.IDomain.LanguageBase&#39 ;.]
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType) +233 System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext,ModelBindingContext bindingContext)+531
System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)+330
System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext,ParameterDescriptor parameterDescriptor)+331
System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext,ActionDescriptor actionDescriptor)+105
System.Web.Mvc.Async&LT;&GT; c__DisplayClass21.b__19(的AsyncCallback asyncCallback,Object asyncState)+743
System.Web.Mvc.Async.WrappedAsyncResult1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +14
1.Begin(的AsyncCallback 回调,对象状态,Int32超时)+128
System.Web.Mvc.Async.WrappedAsyncResultBase
System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext,String actionName,AsyncCallback callback,Object 州)+343
System.Web.Mvc.Controller.b__1c(AsyncCallback的 asyncCallback,Object asyncState,ExecuteCoreState innerState)+25
System.Web.Mvc.Async.WrappedAsyncVoid1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +30
1.Begin(的AsyncCallback 回调,对象状态,Int32超时)+128
System.Web.Mvc.Async.WrappedAsyncResultBase
System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback回调, 对象状态)+465
System.Web.Mvc.Controller.b__14(AsyncCallback的 asyncCallback,Object callbackState,Controller controller)+18
System.Web.Mvc.Async.WrappedAsyncVoid1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +20
1.Begin(的AsyncCallback 回调,对象状态,Int32超时)+128
System.Web.Mvc.Async.WrappedAsyncResultBase
System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback回调,对象状态)+374
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(的RequestContext requestContext,AsyncCallback回调,对象状态)+16
System.Web.Mvc.MvcHandler.b__4(AsyncCallback的 asyncCallback,Object asyncState,ProcessRequestState innerState)+52 System.Web.Mvc.Async.WrappedAsyncVoid1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +30
1.Begin(的AsyncCallback 回调,对象状态,Int32超时)+128
System.Web.Mvc.Async.WrappedAsyncResultBase
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext,AsyncCallback回调,对象状态)+384
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback回调,对象状态)+48
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext的 context,AsyncCallback cb,Object extraData)+16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +103 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+155
我错过了什么吗?
更新
这是我的控制器代码......
using System;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using Visia.MasterData.Banking.DAL;
using Visia.PartyRoles.Core.Banking.IDataServices;
using Visia.PartyRoles.Generic.IDomain;
namespace Visia.CrediScan.UI.Views
{
public class LanguagesController : Controller
{
private readonly QueryBase _query;
private readonly CommandBase _command;
public LanguagesController(QueryBase query, CommandBase command)
{
if (query == null) throw new ArgumentNullException(nameof(query));
if (command == null) throw new ArgumentNullException(nameof(command));
_query = query;
_command = command;
}
// GET: /Languages/Edit/5
public ActionResult Edit(long? id, long CountryId)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var language = _query.GetLanguage((long)id);
if (language == null)
{
return HttpNotFound();
}
ViewBag.CountryId = CountryId;
return View(language);
}
// POST: /Languages/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(LanguageBase language, long CountryId)
{
if (ModelState.IsValid)
{
language.CountryId = CountryId.ToString();
_command.Update(language);
return RedirectToAction("Index", new { CountryId = CountryId });
}
return View(language);
}
}
}
答案 0 :(得分:2)
您的问题与Autofac无关。 MVC框架负责根据请求中的数据为action方法创建参数。
虽然您可以创建自定义模型绑定器(通过IModelBinder
界面)来解决您的问题,但我建议您没有包含行为的操作参数。
相反,创建一个仅包含数据并将其用作操作参数的简单模型(例如Language
)。并且有另一项服务(例如ILanguageService
)包含您可能希望使用DI改变的行为。这种服务将被注入控制器的构造函数中。
看看this article。我看到它的方式,动作方法是你的应用程序的边界。所以你的动作参数不应该是面向对象的,即它们不应该包含行为。它们应该是简单的数据对象。然后,您可以使用其他服务将简单数据对象转换为面向对象(包含行为)的某个对象。然后通过构造函数注入此类服务(因此Autofac可以处理它)。