.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>();

 

2、组件介绍

IServiceCollection 

负责服务的注册

 

ServiceDescriptor 

每一个服务注册时的信息

 

IServiceProvider    (由IServiceCollection   Build出来的

使用的容器(微软默认的,第三方Autofac等等的)

 

IServiceScope

子容器的生命周期

  • Transient(瞬时): 每一次GetService都会创建一个新的实例
  • Scoped(作用域):  在同一个Scope内只初始化一个实例 ,可以理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内)(可以手动创建多个作用域)
  • Singleton (单例):整个应用程序生命周期以内只创建一个实例 

 

 

 

 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>

posted @ 2018-12-11 12:50  西伯利亚的狼  阅读(1605)  评论(0编辑  收藏  举报