一、配置Autofac替换内置DI
1.安装Nuget包:Autofac.Extensions.DependencyInjection
2.Program.cs中加上
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Host.ConfigureContainer(containerBuilder => { //在这里写注入代码 });
二、构造函数注入
新建IUserService,类UserService
public interface IUserService { public string GetUserName(); }
public class UserService:IUserService { public string GetUserName() { return "张三"; } }
在上面的ConfigureContainer方法把UserService注入进来,默认是瞬时注入
瞬时注入:containerBuilder.RegisterType().As().InstancePerDependency();;
单例注入:containerBuilder.RegisterType().As().SingleInstance();
生命周期注入: containerBuilder.RegisterType().As().InstancePerLifetimeScope();
注入试下是否注入成功
调用成功,证明注入成功
三、属性注入
1.把HomeController改成属性注入形式,属性注入有一个问题,就是那些属性需要注入?全部注入没必要,父类也有很多属性,要按需注入,给属性增加一个自定义特性标识说明需要注入。
public class HomeController : Controller { [AutowiredProperty] private IUserService userService { get; set; } public IActionResult Index() { string name = userService.GetUserName(); return View(); } }
2.新增自定义特性类AutowiredPropertyAttribute.cs
[AttributeUsage(AttributeTargets.Property)]//为了支持属性注入,只能打到属性上 public class AutowiredPropertyAttribute: Attribute { }
3.增加识别特性类AutowiredPropertySelector.cs
public class AutowiredPropertySelector : IPropertySelector { public bool InjectProperty(PropertyInfo propertyInfo, object instance) { //判断属性的特性是否包含自定义的属性,标记有返回true return propertyInfo.CustomAttributes.Any(s => s.AttributeType == typeof(AutowiredPropertyAttribute)); } }
4.因为Controller 默认是由 Mvc 模块管理的,需要把控制器放到IOC容器中,在Program.cs中增加
//让控制器实例由容器创建 builder.Services.Replace(ServiceDescriptor.Transient());
5.把容器注册到IOC容器,在Program.cs的ConfigureContainer()增加
//获取所有控制器类型并使用属性注入 Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes() .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray(); containerBuilder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector());
验证:
成功。
四、批量注入
实际项目中那么多需要注入的类,一个个写注册就不太现实了,需要一个可以批量注入的方法。
1.新建三个空接口IScopeDenpendency.cs,ISingletonDenpendency.cs,ITransitDenpendency.cs
////// 瞬时注入 /// public interface ITransitDenpendency { } /// /// 单例注入标识 /// public interface ISingletonDenpendency { } /// /// 生命周期注入标识 /// public interface IScopeDenpendency { }
2.把上面要注入的类实现上面的接口
3.新增一个IocManager类
////// Ioc管理 /// public static class IocManager { /// /// 批量注入扩展 /// /// /// public static void BatchAutowired(this ContainerBuilder builder, Assembly assembly) { var transientType = typeof(ITransitDenpendency); //瞬时注入 var singletonType = typeof(ISingletonDenpendency); //单例注入 var scopeType = typeof(IScopeDenpendency); //单例注入 //瞬时注入 builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(transientType)) .AsSelf() .AsImplementedInterfaces() .InstancePerDependency() .PropertiesAutowired(new AutowiredPropertySelector()); //单例注入 builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(singletonType)) .AsSelf() .AsImplementedInterfaces() .SingleInstance() .PropertiesAutowired(new AutowiredPropertySelector()); //生命周期注入 builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && t.GetInterfaces().Contains(scopeType)) .AsSelf() .AsImplementedInterfaces() .InstancePerLifetimeScope() .PropertiesAutowired(new AutowiredPropertySelector()); }
4.把注入类ConfigureContainer改成
5.防止Program.cs代码过多,建一个Module把注入代码搬走,新建AutofacRegisterModule.cs类把ConfigureContainer的代码移过去
public class AutofacRegisterModule : Autofac.Module { protected override void Load(ContainerBuilder builder) { //获取所有控制器类型并使用属性注入 Type[] controllersTypeAssembly = typeof(Program).Assembly.GetExportedTypes() .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray(); builder.RegisterTypes(controllersTypeAssembly).PropertiesAutowired(new AutowiredPropertySelector()); //批量自动注入,把需要注入层的程序集传参数,注入Service层的类 builder.BatchAutowired(typeof(UserService).Assembly); //注入其它层的containerBuilder.BatchAutowired(typeof(其它层的任务一个类).Assembly); } }
ConfigureContainer的代码变成
五、手动获取实例
手动获取实例的场景有静态帮助类中获取实例,例如redisHelper中获取注入的配置文件中的连接字符串
1.在上面的IocManager类中增加
private static object obj = new object(); private static ILifetimeScope _container { get; set; } public static void InitContainer(ILifetimeScope container) { //防止过程中方法被调用_container发生改变 if (_container == null) { lock (obj) { if (_container == null) { _container = container; } } } } ////// 手动获取实例 /// /// /// public static T Resolve() { return _container.Resolve(); }
2.在Program.cs中增加
3.验证,新建一个DataHelper.cs类
public class DataHelper { //手动注入UserService private static IUserService userService = IocManager.Resolve(); public static string GetData() { return userService.GetUserName(); } }
成功获取到值,证明从容器中获取成功。
六、其它用法
1.不用接口,直接注入实例
public class UserService :ITransitDenpendency { public string GetUserName() { return "张三"; } }
2.一接口多实现
public class UserService :IUserService { public string GetUserName() { return "张三"; } } public class UserService2 : IUserService { public string GetUserName() { return "张三2号"; } }
Arabic | Hebrew | Polish |
Bulgarian | Hindi | Portuguese |
Catalan | Hmong Daw | Romanian |
Chinese Simplified | Hungarian | Russian |
Chinese Traditional | Indonesian | Slovak |
Czech | Italian | Slovenian |
Danish | Japanese | Spanish |
Dutch | Klingon | Swedish |
English | Korean | Thai |
Estonian | Latvian | Turkish |
Finnish | Lithuanian | Ukrainian |
French | Malay | Urdu |
German | Maltese | Vietnamese |
Greek | Norwegian | Welsh |
Haitian Creole | Persian |
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
ChatGPT是美国OpenAI研发的聊天机器人程序,2022年11月30日发布。ChatGPT是人工智能技术驱动的自然语言处理工具,它能够通过理解和学习人类的语言来进行对话。 ChatGPT的原理 ChatGPT是一种基于人工智能技术的自然语言生成模型,它能…