我正在尝试使用StructureMap为我的ASP.NET MVC 4站点设置IoC。这是我的StructureMapDependencyResolver
课程:
public class StructrueMapDependencyResolver : IDependencyResolver
{
public object GetService(Type serviceType)
{
return IocContainer.GetInstance(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return IocContainer.GetAllInstances(serviceType);
}
}
这是我的IocContainer的一部分
public static class IocContainer
{
....
public static object GetInstance(Type t)
{
return ObjectFactory.TryGetInstance(t);
}
public static IEnumerable<object> GetAllInstances(Type t)
{
return ObjectFactory.GetAllInstances(t).Cast<object>();
}
}
这是我的Global.aspx.cs的样子
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
IocContainer.RegisterAllTypes(Server.MapPath("~\\Bin"), AssemblyList.MyAssemblies);
DependencyResolver.SetResolver(new StructrueMapDependencyResolver());
}
}
最后,我有一个依赖于服务的简单控制器:
public class ManagePostController: Controller
{
private ISomeService _someService;
public ManagePostController(ISomeService svc)
{
_someService= svc;
}
}
当我启动我的网站时,遇到以下异常:
没有为此对象定义无参数构造函数。
[InvalidOperationException:尝试创建“Foothill.WebAdmin.Controllers.ManagePostController”类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。] System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext,Type controllerType)+247
我不确定我需要改变的地方?
答案 0 :(得分:4)
将您的IocContainer.GetInstance(Type)
实施替换为以下内容:
public static object GetInstance(Type t)
{
return t.IsAbstract || t.IsInterface
? ObjectFactory.TryGetInstance(t)
: ObjectFactory.GetInstance(t);
}
ASP.NET MVC可扩展性模型将尝试解析可选的各种组件(例如IControllerActivator
)(如果返回null
,则MVC将使用默认组件)。这就是我们进行ObjectFactory.TryGetInstance
调用的原因 - 如果您在容器中明确配置它,它将只解析一个组件。
对于解析控制器(具体类型)应该使用ObjectFactory.GetInstance
- 即使从未显式配置控制器类型,也会创建一个实例。
上面的代码片段是我在项目中使用的代码片段,我刚刚意识到它与StructureMap MVC4 Nuget包中的内容非常相似(参见this file中的第123行)。
顺便说一下,我认为你可以简单地使用the NuGet package而不是自己完成这些步骤。
关于IControllerActivator
:这只是另一个可扩展性点。如果未注册控制器激活器,则使用依赖性解析器:
如果依赖项解析程序中没有IControllerActivator,我们将通过调用GetService(controllerType)请求依赖项解析程序创建具体的控制器类型。(引自Brad Wilson's blog)
此外,解释为什么同时存在IDependencyResolver
和IControllerActivator
:http://forums.asp.net/post/4241343.aspx
答案 1 :(得分:0)
我在使用IoC容器时遇到了同样的问题并且谷歌搜索了几个小时但是无法摆脱它。最后我安装了Visual Studio的最新更新(VS版本2013和我的情况下的update3)并且问题得到了解决。< / p>