解决Autofac MVC 自动注入在 Areas拆分到不同dll下的注入失败问题
由于项目业务复杂,创建了多个Areas 并把他们放在了不同的项目中,项目使用AutoFac做的IOC
配置代码为
1 public class MvcApplication : System.Web.HttpApplication 2 { 3 protected void Application_Start() 4 { 5 //依赖注入 6 var builder = new ContainerBuilder(); 7 builder.RegisterModule(new ConfigurationSettingsReader("autofac")); 8 builder.RegisterControllers(Assembly.GetExecutingAssembly()); 9 10 var container = builder.Build(); 11 DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 12 13 AreaRegistration.RegisterAllAreas(); 14 WebApiConfig.Register(GlobalConfiguration.Configuration); 15 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 16 RouteConfig.RegisterRoutes(RouteTable.Routes); 17 } 18 }
在 Controllers中 采用 构造函数来实现注入
namespace xxx.Web.Person.Controllers { /// <summary> /// 定位模块 /// </summary> public class LocationController : Controller { private ILocationService _location; public LocationController(ILocationService location) { _location = location; } } }
启动后报错 错误信息:
[MissingMethodException: 没有为该对象定义无参数的构造函数。] System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241 System.Activator.CreateInstance(Type type, Boolean nonPublic) +69 System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67
[InvalidOperationException: 尝试创建“xxx.Web.Person.Controllers.HomeController”类型的控制器时出错。请确保控制器具有无参数公共构造函数。]
通过错误信息得知 AutoFac 的RegisterControllers 只是 注入了xxx.Web的 Controllers 对于引用的 xxx.web.Person.dll 下的 Controller 没有注入。
解决方法如下:
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { //依赖注入 var builder = new ContainerBuilder(); builder.RegisterModule(new ConfigurationSettingsReader("autofac")); builder.RegisterControllers(Assembly.GetExecutingAssembly()); //解决Areas在不同的Dll中注入问题 var assemblies = new DirectoryInfo( HttpContext.Current.Server.MapPath("~/bin/")) .GetFiles("*.dll") .Select(r => Assembly.LoadFrom(r.FullName)).ToArray(); builder.RegisterAssemblyTypes(assemblies) .Where(r => r.BaseType == typeof(Controller)) .InstancePerHttpRequest(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); } }
重新编译 运行正常。