.NET Core IOC AOP
IOC简介
IOC思想
把类当做组件或服务来看待,组件内一定要高内聚,组件之间一定要低耦合,既然要保持低耦合,那就一定不要轻易的去new什么对象。
那组件之间的交互怎么处理呢?那最好的方式就是把new的操作交给第三方的治理框架去做,
比如往大处说的“Dubbo”, Spring Cloud(服务注册,服务发现,服务自动下线,流量分配,熔断,降级),往小处说就是IOC容器
把类往大处想。
把治理框架往小处想。。
IOC能做到那些
1. 对接口和实现类实现了由原来的零散式管理到现在的集中化管理。 (集中化日志,集中化配置系统 etcd,zookeeper)
new
业务驱动 IOC
产品驱动
2. 对类之间,类接口之间的关联关系可以采用多种模式注入(构造器注入,属性注入)等等。
3. 对实现类的生命周期进行了统一管理,能够控制服务的创建,释放和监控。
4. 对类的依赖由编译时推迟到了运行时。
依赖注入框架
也就是我们经常说的ioc框架
借助依赖注入框架,我们可以轻松管理类与类之间的依赖,帮助我们在构建应用时遵循设计原则,却宝宝代码的可维护性和扩展性。
在asp.net core中各框架中,依赖注入框架体哦那个了对象的创建和生命周期管理的核心能力。以及各个组件的相互协作,也是由依赖注入框架的能力来实现的。
.NET Core中IOC
1、简单使用
NUGet 包
Microsoft.Extensions.DependencyInjection.Abstractions
Microsoft.Extensions.DependencyInjection
是抽象实现分离的原则。我们只需要引用他的抽象包。使用的时候注入他具体的实现即可。 好处使用的时候指定具体的实现。未来可以灵活的替换具体的实现。底层不需要改动。
//IOC容器
ServiceCollection services = new ServiceCollection();
//注册服务 每次调用都创建新的类
services.AddTransient<IUserCQRS, UserCQRS>();
////注册服务 只new一次
//services.AddSingleton<IUserCQRS, UserCQRS>();
services.AddSingleton<IUserCQRS>(new UserCQRS());
//工厂注入 这里的serviceProvider 我们可以重新从容器里面获取多个服务进行组装操作
services.AddSingleton<IUserCQRS>(serviceProvider => { return new UserCQRS(); });
//尝试注册,注册过就不在注册了 。实现是不同的还可以继续注册
services.TryAddEnumerable(ServiceDescriptor.Singleton<IUserCQRS, UserCQRS>());
//尝试注册,注册过就不在注册了。实现不同 也不能注册
services.TryAddSingleton<IUserCQRS, UserCQRS>();
#region 替换别人注册进去的服务
services.RemoveAll<IUserCQRS>();
services.RemoveAll(typeof(IUserCQRS));
//IUserCQRS 的实现替换为 UserCQRS
services.Replace(ServiceDescriptor.Singleton<IUserCQRS, UserCQRS>());
#endregion
#region 泛型注册
//services.AddSingleton<typeof(IUserCQRS<>),typeof(UserCQRS<>) > ();
#endregion
//在某个作用于中就是一个单利
services.AddScoped<IUserCommand, UserCommand>();
//服务提供者
var serviceProvider = services.BuildServiceProvider();
var userQCRSImp = serviceProvider.GetService<IUserCQRS>();
Console.WriteLine(userQCRSImp.GetUserName("lalala"));
//创建作用域 usercommand1 usercommand2 同一个实例 usercommand4 usercommand3 同一个实例
var scope1 = serviceProvider.CreateScope();
var usercommand1 = scope1.ServiceProvider.GetService<IUserCommand>();
var usercommand2 = scope1.ServiceProvider.GetService<IUserCommand>();
var scope2 = serviceProvider.CreateScope();
var usercommand3 = scope2.ServiceProvider.GetService<IUserCommand>();
var usercommand4 = scope2.ServiceProvider.GetService<IUserCommand>();
3、作用域 与 生命周期与 Disposable
子容器:容器里面还有创建其他容器。 比如说scope里面在创建一个scope
对于实现了IDisposable类的实例的对象,容器会负责对其生命周期管理,使用完毕后会对其释放。(容器释放会释放他创建的服务)
使用注意:
DI只负责释放由其创建的对象实例
例如:
Con con=new Con();
.AddSigleton<IConf>(con);(con不会被容器释放) 他只负责他创建的对象,不负责别人创建的对象
但是
.AddSigleton<IConf>(p=>con);工厂模式注入,会被容器释放
DI在容器或子容器起释放时,释放由其创建的对象实例。
使用建议:
避免在跟容器获取实现了IDisposable接口的瞬时服务,(原因,单例的生命周期其实是根容器,在跟容器获取实现了IDisposable接口的瞬时服务 生命周期会和根容器一起,程序结束才释放)
避免手动创建实现了IDisposable的对象,应使用容器创建对象
4、基于名称注入,基于属性注入,动态代理(aop),子容器
自带的不支持名称注入 和 属性注入,可以使用Autofac组件
使用方式
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } --Startup类中加入 public void ConfigureContainer(ContainerBuilder builder) { }
public void ConfigureContainer(ContainerBuilder builder) { //builder.RegisterType<MyService>().As<IMyService>(); #region 命名注册 //builder.RegisterType<MyServiceV2>().Named<IMyService>("service2"); #endregion #region 属性注册 //builder.RegisterType<MyNameService>(); //builder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired(); #endregion #region AOP //builder.RegisterType<MyInterceptor>(); //builder.RegisterType<MyNameService>(); //builder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired().InterceptedBy(typeof(MyInterceptor)).EnableInterfaceInterceptors();//接口拦截器 和 类拦截器(虚方法) #endregion #region 子容器 创建在子容器里面,其他的容器获取不到这个服务 builder.RegisterType<MyNameService>().InstancePerMatchingLifetimeScope("myscope"); #endregion }
子容器 创建scope实现子容器
AOP介绍
AOP思想
我们知道AOP是面向切面编程,很好的解决了系统级的功能和业务功能的耦合问题。。。
.NETCore AOP实现
nuget包 AspectCore.Extensions.DependencyInjection 对应github地址:https://github.com/dotnetcore/AspectCore-Framework 源码中有帮助文档
他也是基于IOC容器的。
第三方的IOC容器都是继承了 public interface IServiceProviderFactory<TContainerBuilder>