zoukankan      html  css  js  c++  java
  • ABP依赖注入

    ASP.NET CORE自带的Microsoft.Extensions.DependencyInjection 依赖注入容器 不支持属性注入  不支持批量注入

    ABP使用依赖注入框架是Castle.Windsor

    .NET Core创建的项目返回类型是ConfigureService  在这里变成了IServiceProvider   这是因为在AddAbp方法内部替换了内置的Ioc容器

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        return services.AddAbp<HKAbpDemoHostModule>();
    }

    都是在module的Initialize(初始化)方法中注册程序集  实现了下面三种接口的都会被自动注册到依赖

        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
        }

    提供了三个自动实现依赖注入的接口

    ITransientDependency  每次都是一个新实例

    ISingletonDependency  全局共用一个实例

    IPerWebRequestDependency  没用到过

    实现这三个接口的自动依赖注入   在Abp.Dependency     BasicConventionalRegistrar这个类中实现

        public class BasicConventionalRegistrar : IConventionalDependencyRegistrar
        {
            public void RegisterAssembly(IConventionalRegistrationContext context)
            {
                //其注册所有继承至ITransientDependency,ISingletonDependency和IInterceptor接口的类。
                //Transient
                context.IocManager.IocContainer.Register(
                    //准备注册的类型 从获取传递过来的程序集
                    Classes.FromAssembly(context.Assembly)
                        //扫描获取类 包括非公用的
                        .IncludeNonPublicTypes()
                        //当前类型需要继承ITransientDependency
                        .BasedOn<ITransientDependency>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .WithService.Self()
                        .WithService.DefaultInterfaces()
                        //注册为瞬态  每次都是创建新实例
                        .LifestyleTransient()
                    );
    
                //Singleton
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<ISingletonDependency>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .WithService.Self()
                        .WithService.DefaultInterfaces()
                        .LifestyleSingleton()
                    );
    
                //Windsor Interceptors
                context.IocManager.IocContainer.Register(
                    Classes.FromAssembly(context.Assembly)
                        .IncludeNonPublicTypes()
                        .BasedOn<IInterceptor>()
                        .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                        .WithService.Self()
                        .LifestyleTransient()
                    );
            }
        }

     每一个Module的初始化方法都会调用下面 IocManager.RegisterAssemblyByConvention()  这个方法会对当前程序集进行解析   实现上面三个接口的实现注入

            public override void Initialize()
            {
                IocManager.RegisterAssemblyByConvention(typeof(IMSEntityFrameworkModule).GetAssembly());
            }

    比如要调用其他Applicaton中的方法 

      可以直接获取当前类型的实例然后调用里面的方法

      await iocManager.Resolve<CustomerAddressAppService>().GetListByCustomerId(null); 

    • IIocRegistrar:用于注册依赖项的类的接口
    • IIocResolver:用于解析依赖的类的接口
    • IIocManager:用于注册和解析依赖项的接口

    IIocManager 本身则是封装了一个 Castle Windsor 的 Ioc 容器

    IocManager内部维护一个private readonly List<IConventionalDependencyRegistrar> _conventionalRegistrars;   存放了所有进行过注册的信息

    public interface IIocManager : IIocRegistrar, IIocResolver, IDisposable
    {
        /// <summary>
        /// Reference to the Castle Windsor Container.
        /// </summary>
        IWindsorContainer IocContainer { get; }
    
        /// <summary>
        /// Checks whether given type is registered before.
        /// </summary>
        /// <param name="type">Type to check</param>
        new bool IsRegistered(Type type);
    
        /// <summary>
        /// Checks whether given type is registered before.
        /// </summary>
        /// <typeparam name="T">Type to check</typeparam>
        new bool IsRegistered<T>();
    }
    public class MySampleClass : ITransientDependency
    {
        private readonly IIocResolver _iocResolver;
    
        public MySampleClass(IIocResolver iocResolver)
        {
            _iocResolver = iocResolver;
        }
    
        public void DoIt()
        {
            //解析, 使用并手动释放
            var personService1 = _iocResolver.Resolve<PersonAppService>();
            personService1.CreatePerson(new CreatePersonInput { Name = "Yunus", Surname = "Emre" });
    //调用Release来手动解析一个对象是很关键的,否则,应用会有内存泄漏问题。为了确保释放对象,要尽可能使用ResolveAsDisPosable(如例子中演示的那样)。在using块的末尾会自动地调用Release。 _iocResolver.Release(personService1);
    //解析并使用using语法糖来释放资源 using (var personService2 = _iocResolver.ResolveAsDisposable<PersonAppService>()) { personService2.Object.CreatePerson(new CreatePersonInput { Name = "Yunus", Surname = "Emre" }); } } }

    对于没有自动注册到DI容器的对象   可以通过下面的方式进行手动注册

    在Startup.cs中 services.AddTransient<IHttpHelp, HttpHelp>();

    IocManager.Register<IHttpHelp, HttpHelp>(DependencyLifeStyle.Transient);

    构造函数注入执行顺序优先于属性注入   

    使用.NET Core 自带的依赖注入容器   后注册的会替换之前注册的

                services.AddTransient<IPer, PersonA>();
                var a = services.BuildServiceProvider().GetService<IPer>();
    
                services.AddTransient<IPer, PersonB>();
                var b = services.BuildServiceProvider().GetService<IPer>();

    使用abp自带的Castle.Windsor依赖注入容器后    后注册的不会替换之前注册的    

                IocManager.Register<IPer, PersonA>();
                IocManager.Register<IPer, PersonB>();

     下面调用替换服务的方式也没有替换之前注册的服务   需要引用using Abp.Configuration.Startup;

     Configuration.ReplaceService<IPer, PersonB>();
  • 相关阅读:
    OpenGLES 怎样在十天内掌握线性代数
    Matlab自己定义函数
    小小小女神啊~~~
    Format类及其子类功能和使用方法具体解释
    数据库集群
    分布式SESSION
    二级缓存
    应用服务器集群部署
    业务拆分和分级
    最简中间件集群方案
  • 原文地址:https://www.cnblogs.com/jiangchengbiao/p/10310943.html
Copyright © 2011-2022 走看看