.NET Framework 4.7项目依赖注入配置问题求助
问题分析与解决方案
错误原因
- 实例方法调用错误:你的
IOC.ConfigureServices是实例方法,不能直接通过类名调用,必须先创建IOC类的实例再调用方法,这是导致“需要对象引用”错误的直接原因。 - 缺少控制器激活器配置:.NET Framework 4.7的MVC默认不会自动使用
ServiceCollection作为依赖注入容器,需要手动替换MVC的控制器激活器,让它使用我们构建的ServiceProvider来解析控制器实例。
修正步骤
1. 修正IOC类的调用方式
在Global.asax.cs的Application_Start中,先创建IOC实例再调用方法,同时构建服务提供者并替换MVC的依赖解析器:
protected void Application_Start() { var services = new ServiceCollection(); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // 创建IOC实例并调用配置方法 new IOC().ConfigureServices(services); // 构建ServiceProvider,替换MVC默认的依赖解析器 var serviceProvider = services.BuildServiceProvider(); DependencyResolver.SetResolver(new CustomDependencyResolver(serviceProvider)); }
2. 实现自定义依赖解析器
创建一个实现IDependencyResolver的类,让MVC使用我们的服务提供者来解析依赖:
public class CustomDependencyResolver : IDependencyResolver { private readonly IServiceProvider _serviceProvider; public CustomDependencyResolver(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public object GetService(Type serviceType) { return _serviceProvider.GetService(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return _serviceProvider.GetServices(serviceType); } }
3. 优化控制器构造函数
你的控制器存在两个构造函数,MVC可能会优先调用无参构造函数,导致_homeMapper为null。建议删除无参构造函数,同时将构造函数参数改为接口类型(符合依赖倒置原则):
private IMapper1<string, HomeViewModel> _homeMapper; public HomeController(IMapper1<string, HomeViewModel> homeViewModelMapper) { _homeMapper = homeViewModelMapper ?? throw new ArgumentNullException(nameof(homeViewModelMapper)); } public ActionResult Index() { var viewModel = _homeMapper.Map("test"); return View(viewModel); }
4. 可选:使用第三方DI容器(更简便)
如果觉得手动实现麻烦,可以使用成熟的第三方容器(如Autofac、Ninject),它们有专门的MVC集成包:
以Autofac为例:
- 安装NuGet包:
Autofac.Mvc5 - 在
Global.asax.cs中配置:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); var builder = new ContainerBuilder(); // 注册所有控制器 builder.RegisterControllers(typeof(MvcApplication).Assembly); // 注册映射服务 builder.RegisterType<HomeViewModelMapper>().As<IMapper1<string, HomeViewModel>>().SingleInstance(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); }
关键注意点
- .NET Framework MVC没有原生集成
ServiceCollection,必须手动对接容器与控制器激活逻辑。 - 确保控制器只有一个带依赖的构造函数,避免MVC选择无参构造函数导致注入失败。
- 注册服务时优先使用接口类型,遵循依赖倒置原则,提升代码可扩展性。
内容的提问来源于stack exchange,提问作者antoine foulon
相关产品推荐
相关产品推荐

