使用Simple Injector向MVC控制器构造函数注入时未注册参数



使用Simple Injector将依赖项注入MVC控制器似乎有一个非常基本的问题。我是使用Simple Injector的新手,以前使用过StructureMap。

MVC的版本是4.5,它是从NuGet安装的Simple Injector的最新版本。

我在查看HomeController的/Index视图时遇到的错误是:

HomeController类型的构造函数包含未注册的名为"context"的IContext类型的参数。请确保IContext已在容器中注册,或者更改HomeController的构造函数。

控制器如下:

public class HomeController : Controller
{
public HomeController(IContext context) { }
public ActionResult Index() { }
}

IContext只是一个简单的接口:

public interface IContext
{
}

具体的IContext实现也很简单,只是常规DbContext的包装器。

public class DbContext : System.Data.Entity.DbContext, IContext
{ 
}

关于信息,IContext接口与DbContext实现位于不同的VS项目/程序集中。MVC项目引用了这些内容。

我的Global.asax.cs中有以下内容:

protected void Application_Start()
{
var container = new Container();
container.Register<IContext, DbContext>();
container.RegisterMvcControllers(System.Reflection.Assembly.GetExecutingAssembly());
container.RegisterMvcAttributeFilterProvider();
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
// Regular MVC startup
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}

这是堆栈跟踪:

[ActivationException: The constructor of the type HomeController contains the parameter of type IContext with name 'context' that is not registered. Please ensure IContext is registered in the container, or change the constructor of HomeController.]
SimpleInjector.Advanced.DefaultConstructorInjectionBehavior.BuildParameterExpression(ParameterInfo parameter) +229
SimpleInjector.Registration.BuildParameterExpressionFor(ParameterInfo parameter) +43
SimpleInjector.Registration.BuildConstructorParameters(ConstructorInfo constructor) +170
SimpleInjector.Registration.BuildNewExpression(Type serviceType, Type implementationType) +62
SimpleInjector.Registration.BuildTransientExpression() +85
SimpleInjector.Registration.BuildExpression(InstanceProducer producer) +62
SimpleInjector.InstanceProducer.BuildExpressionInternal() +42
System.Lazy`1.CreateValue() +14443208
System.Lazy`1.LazyInitValue() +476
SimpleInjector.InstanceProducer.BuildExpression() +159
[ActivationException: The registered delegate for type HomeController threw an exception. The     constructor of the type HomeController contains the parameter of type IContext with name 'context' that is not registered. Please ensure IContext is registered in the container, or change the constructor of HomeController.]
SimpleInjector.InstanceProducer.BuildExpression() +257
SimpleInjector.InstanceProducer.VerifyExpressionBuilding() +53
[InvalidOperationException: The configuration is invalid. Creating the instance for type HomeController failed. The registered delegate for type HomeController threw an exception. The constructor of the type HomeController contains the parameter of type IContext with name 'context' that is not registered. Please ensure IContext is registered in the container, or change the constructor of HomeController.]
SimpleInjector.InstanceProducer.VerifyExpressionBuilding() +161
SimpleInjector.Container.VerifyIfAllExpressionsCanBeBuilt(InstanceProducer[] producersToVerify) +45
SimpleInjector.Container.VerifyIfAllExpressionsCanBeBuilt() +166
SimpleInjector.Container.Verify() +39
MyMvcApp.App_Start.SimpleInjectorInitializer.Initialize() +216
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +229
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +193
System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +35       
WebActivator.BaseActivationMethodAttribute.InvokeMethod() +341
WebActivator.ActivationManager.RunActivationMethods() +534
WebActivator.ActivationManager.RunPostStartMethods() +38
WebActivator.StartMethodCallingModule.Init(HttpApplication context) +159
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +530
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +304
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +404
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +475
[HttpException (0x80004005): Exception has been thrown by the target of an invocation.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +12889028
System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +159
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +12730121

我不知道为什么它不起作用,因为代码都是按照Simple Injector快速启动指南编写的。

确保HomeController引用的IContext实际上与您在Application_Start中注册的IContext类型相同。很可能,这是另一种类型。在注册的IContextHomeControllerIContext上对Visual Studio执行"转到定义",可以确认Visual Studio是否跳转到同一文件。

另一件需要检查的事情是,代码中显示的Container实例是否是在MVC中注册的实际(也是唯一)容器。在您的申请中搜索任何其他new Container注册。

当您的配置实际上包含具有相同名称的不同类型时,Simple Injector的较新版本实际上会警告您一个非常特定的错误,因此使用Simple Inject应该很容易检测到这些问题。当这种情况由不正确的动态程序集加载引起时,异常消息会更加具体。

最新更新