一起聊聊Microsoft.Extensions.DependencyInjection

本文探讨了Microsoft.Extensions.DependencyInjection在.NET Core中的广泛应用,它作为一个DI容器,不仅提供了默认实现,还支持第三方IOC容器。通过详细讲解IServiceCollection和IApplicationBuilder,以及如何在Startup中注册和初始化服务,阐述了其在框架和业务层的重要性。此外,文章还展示了如何自定义模块并整合到.NET Core中。

Microsoft.Extensions.DependencyInjection在github上同样是开源的,它在dotnetcore里被广泛的使用,比起之前的autofac,unity来说,它可以说是个包裹,或者叫适配器,它自己提供了默认的DI实现,同时也支持第三方的IOC容器,在这段时间里使用了它,就想,这东西为什么被在dotnetcore里大放异彩?为什么会全程使用它?从程序的开始到程序启动起来,你可以发现它无处不在,在框架里是这样,在业务层同时也是这样。

聊聊Microsoft.Extensions.DependencyInjection知识点包括

  1. 它的开源地址

  2. IServiceCollection和IApplicationBuilder

  3. 自定义模块用它

  4. 在Startup.ConfigureServices中注册自定义模块

  5. 在Startup.Configure中使用它,进行默认模块的初始化

  6. 在任意对象的构造方法中使用它

一步一步的揭秘

一 它的开源地址

https://github.com/aspnet/DependencyInjection

可以看看它的README.md,就知道它是个大包裹,类似于大叔LindAgile里的Container,完全可以扩展支持其它第三方的IOC容器,这就像大叔经常说的那句话一样,在IT江湖中,英雄总是所风略同……

二 dotnetcore整个框架在用它

在你的dotnetcore应用程序里,你会发现在Startup类中有很多像services.AddMvc()这样的方法,这实质是像应用程序中注册一个组件,这里的MVC是一个统一的组件,它不依赖于windows,不依赖于dotnet,整个dotnetcore里把很多组件都解耦了,这样在维护和nuget包升级时都更灵活,自己有问题就优化自己,而不影响其它模块。(越说越像微服务的宗旨)。

IServiceCollection主要用来注册服务,就是某个接口和某种实现的对应关系,这种注册是我们在Startup.ConfigureServices方法里完成的,如下面的AddLind()这个方法,它完成了对Lind模块的注册,在方法内部可以注册本模块的其它服务。


        /// <summary>
        /// 添加Lind框架和它们依赖子模块    
      
/// </summary> /// <param name="services"></param> /// <param name="setupAction"></param> /// <returns></returns> public static LindBuilder AddLind(      
     
this IServiceCollection services,            Action<LindOptions> setupAction)        {          
  
if (setupAction == null) throw
<think>好的,我现在需要解决用户在.NET项目中遇到的CS0121编译错误,具体是关于AddAutoMapper方法调用的二义性问题。用户提到使用了AutoMapper和AutoMapper.Extensions.Microsoft.DependencyInjection这两个包,可能是在升级项目版本时出现了问题。首先,我需要回忆一下这个错误通常是什么原因引起的。 CS0121错误通常发生在编译器无法确定使用哪个方法重载的时候,也就是存在多个重载方法匹配参数,导致编译器无法选择。在这种情况下,用户调用了AddAutoMapper方法,但存在多个可能的扩展方法,参数类型或数量不同,导致冲突。 接下来,我需要了解AutoMapper.Extensions.Microsoft.DependencyInjection这个库在不同版本中的变化。根据用户提供的引用[1],可能涉及到不同版本的.NET Core或.NET 5/6/7/8的升级问题。例如,在旧版本中,AddAutoMapper可能接受一个params Assembly[]参数,而新版本可能添加了其他重载,比如接受ServiceLifetime参数,或者使用泛型类型参数指定程序集。 用户可能同时引用了不同版本的AutoMapper和其扩展包,或者项目中存在多个程序集导致编译器无法推断该使用哪个重载。这时候,解决方法可能需要明确指定参数类型,或者显式调用某个特定的扩展方法。 查阅引用资料中的链接,比如引用[2]中的升级指南,可能在升级到.NET 8或9时,某些API发生了变化。不过用户的问题更直接相关的是AutoMapper扩展方法的使用。另外,引用[3]中的Vicuna模型可能不相关,但其他引用可能提供线索。 解决方案可能包括以下几种: 1. 显式指定参数类型,例如将程序集转换为Assembly[],以匹配特定的重载方法。 2. 使用泛型方法指定启动类所在的程序集,如AddAutoMapper<Startup>()。 3. 检查NuGet包的版本,确保AutoMapper和其扩展包版本兼容,可能需要升级或回退版本。 4. 使用完全限定名来调用方法,避免扩展方法冲突。 例如,旧版本的AddAutoMapper可能接受params Assembly[],而新版本可能有AddAutoMapper(ServiceLifetime)或者AddAutoMapper(params Assembly[])。如果用户同时引用了多个扩展方法,编译器可能无法确定使用哪一个。 用户可能在代码中写了类似services.AddAutoMapper();,但没有传递任何参数,而新版本可能需要明确指定参数。或者用户传递的参数类型不明确,比如传递了一个类型,而存在多个重载可以接受不同的参数类型。 另一个可能性是,用户同时引用了另一个库,该库也定义了AddAutoMapper的扩展方法,导致冲突。这时候需要明确指定使用哪个命名空间下的扩展方法。 因此,具体的解决步骤可能包括: - 检查AutoMapper.Extensions.Microsoft.DependencyInjection的版本,确保与AutoMapper主包版本兼容。 - 明确调用扩展方法时传递正确的参数,如指定程序集或使用泛型类型。 - 使用完全限定名或别名来消除歧义。 - 清理并重新生成解决方案,确保没有旧的缓存导致的问题。 例如,代码中可能应该改为services.AddAutoMapper(typeof(Startup).Assembly); 或者services.AddAutoMapper(Assembly.GetExecutingAssembly()); 来明确指定程序集参数,从而匹配正确的重载方法。 另外,用户可能在升级项目后,扩展方法的参数发生了变化,比如现在需要传递ServiceLifetime,所以需要添加额外的参数,或者使用新的方法签名。 总结,用户需要明确指定AddAutoMapper的参数,确保调用的是正确的重载方法,同时检查包的版本兼容性,避免不同版本之间的API冲突。</think>### CS0121编译错误:AddAutoMapper方法重载冲突解决方案 在.NET项目中使用AutoMapper时,若同时引用`AutoMapper`和`AutoMapper.Extensions.Microsoft.DependencyInjection`包,调用`AddAutoMapper`方法可能因**方法重载解析冲突**导致CS0121错误。以下是具体原因及解决方案: --- #### **原因分析** 1. **包版本不兼容** - 旧版本(如.NET Core 3.1或.NET 5)中,`AddAutoMapper`方法可能仅支持`params Assembly[]`参数。 - 新版本(如.NET 6/7/8)可能引入了其他重载,例如支持`ServiceLifetime`参数或泛型类型[^1][^2]。 2. **参数推断失败** 编译器无法确定应使用哪个重载方法,尤其是当参数类型不明确时。例如: ```csharp services.AddAutoMapper(); // 无参数时可能匹配多个重载 ``` --- #### **解决方案** ##### 方法1:显式指定程序集参数 通过传递**明确的程序集参数**,帮助编译器匹配正确的重载: ```csharp // 方式1:通过类型指定程序集 services.AddAutoMapper(typeof(Startup).Assembly); // 方式2:直接获取当前程序集 services.AddAutoMapper(Assembly.GetExecutingAssembly()); ``` ##### 方法2:使用泛型类型指定程序集 若扩展包支持泛型方法,可指定启动类类型: ```csharp services.AddAutoMapper<Startup>(); ``` ##### 方法3:完全限定方法名 通过命名空间消除歧义: ```csharp using AutoMapper; // 显式调用特定扩展方法 Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions .AddAutoMapper(services, typeof(Startup).Assembly); ``` ##### 方法4:检查包版本兼容性 1. 升级`AutoMapper`和`AutoMapper.Extensions.Microsoft.DependencyInjection`到**兼容版本**。 - 对于.NET 8.0项目,确保使用`AutoMapper 12.0.1`及以上版本[^2]。 2. 清理解决方案并重新生成项目,避免旧版本缓存干扰。 --- #### **验证示例** 假设项目中包含`Profile`类(如`UserProfile`),正确配置后应能正常注册映射: ```csharp // Profile类定义 public class UserProfile : Profile { public UserProfile() { CreateMap<User, UserDto>(); } } // 在Startup.cs中配置 services.AddAutoMapper(Assembly.GetExecutingAssembly()); ``` --- #### **避免冲突的最佳实践** 1. **统一包版本** 确保所有相关包(如`AutoMapper`、`AutoMapper.Extensions.Microsoft.DependencyInjection`)版本匹配。 2. **明确程序集范围** 限制AutoMapper扫描的程序集,减少性能损耗和冲突风险。 3. **定期升级指南** 参考微软官方升级文档(如[.NET Core 3.1到.NET 7.0升级指南](https://blog.csdn.net/hefeng_aspnet/article/details/130128864))。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值