ABP - 依赖注入(2)

这篇具有很好参考价值的文章主要介绍了ABP - 依赖注入(2)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

依赖注入的使用

构造方法注入

这是将服务注入类的最常用方法,是将依赖项注入类的首选方式,也是微软推崇的模式。这样,除非提供了所有构造方法注入的依赖项,否则无法构造类,显示的声明了类必需的服务,使开发人员一目了然。

public class BookAppService : ApplicationService
{
    private readonly IBookRepository _bookRepository;
		public TaxAppService(IBookRepository bookRepository)
    {
        _bookRepository = bookRepository;
    }
		public void DoSomething()
    {
        //...使用 _bookRepository...
    }
}

属性注入

Microsoft依赖注入库不支持属性注入, 属性注入是Abp框架使用autofac容器替换了微软默认的容器之后才能使用的,属于autofac的特性。

public class BookAppService : ITransientDependency
{
	public ILogger<BookAppService> Logger { get; set; }
	public BookAppService()
	{
        Logger = NullLogger<BookAppService>.Instance;
	}
	
	public void DoSomething()
	{
        //...使用 Logger 写日志...
	}
}

属性注入依赖项通常被视为可选依赖项.这意味着不是必须的,没有它们服务也可以正常工作.Logger就是这样的依赖项,BookAppService可以继续工作而无需日志记录。为了使依赖项成为可选的,我们通常会为依赖项设置默认值。一般是接口的一个空实现,内部不做任何操作。

属性注入的一个限制是你不能在构造函数中使用依赖项,因为它是在对象构造之后设置的.

从IServiceProvider解析服务

public class MyService : ITransientDependency
{
    private readonly IServiceProvider _serviceProvider;
	public MyService(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }
	
	public void DoSomething()
    {
        
		using (var scope = _serviceProvider.CreateScope())
		{
			var service1 = scope.ServiceProvider.GetService<IMyService1>();
			// …
		}
	}
}

通过GetServiceGetRequiredService可以直接从容器中解析出我们需要的服务,这两个方法有一定的区别,推荐使用GetRequiredService方法。

这种情况下一般会使用using (var scope = _serviceProvider.CreateScope()){} 创建一个域,以便解析出来的服务能够安全的被释放,这也能够减少一些内存消耗。

要注意的一个点是,在以前的ASP.NET Boilerplate 中服务的手动解析使用是通过IocManager的,这是静态类,通过IocManager.Instance可以获得容器对象,很方便使用。但是在现在的ABP中已经将这种方式移除了,以至于有时候在静态类中需要使用一些服务的时候很不方便(虽然这种方式不是很正确,但是确实有时候会有这样子的需求)。

所以在项目中如果真的有需要的话,可以自己构建一个类似于IocManager的方式,但是不推荐这样子用,因为在某些情况确实会存在一些问题,导致一些资源和生命周期的冲突,特别是在单元测试之中。

/// <summary>
/// ServiceManager构建一个单例,用于寄放IServiceProvider
/// 使用此类时,需要在应用启动的时候,调用Init方法
/// 一般情况下不推荐使用
/// </summary>
public class ServiceManager
{
	private ServiceManager()
	{
	}

	public static IServiceProvider ServiceProvider { get; private set; }

	public static void Init(IServiceProvider service)
	{
		ServiceProvider = service;
	}
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
	var app = context.GetApplicationBuilder();
	// 保存全局Ioc
	if (app != null)
	{
		ServiceManager.Init(app.ApplicationServices);
	}
}

Autofac的使用

容器替换

Abp框架中使用autofac依赖注入框架替换了微软默认的容器,在volo.abp.autofac模块中按照模块化设计的思想进行了稍微的封装,提供了便捷的替换方式。

使用autofac替换默认容器的方式:

(1) 在startup类中的ConfigureServices()中,在添加Abp的依赖注入时,通过选项替换。

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddApplication<MyWebModule>(options =>
    {
        //Integrate Autofac!
        options.UseAutofac();
    });
    return services.BuildServiceProviderFromFactory();
}

(2) 在program.cs中,在.net Core 主机(host)创建的时候,调用userAutofac()扩展方法。

internal static IHostBuilder CreateHostBuilder(string[] args) =>
	            Host.CreateDefaultBuilder(args)
	                .ConfigureWebHostDefaults(webBuilder =>
	                {
	                    webBuilder.UseStartup<Startup>();
	                })
                .UseAutofac();

拦截器与动态代理

Abp框架使用autofac替换微软默认容器的目的,主要就是为了利用autofac的拦截器功能,这是一种动态aop的实现方式,可以动态的拦截往容器中注册的类,做一些想要的操作。abp框架中的很多横切关注点都是通过这种方式实现的,如权限认证,审计等。

在模块类的PreConfigureServices()中,可以使用OnRegistred()方法,注册一个回调,每次有类向容器中注册时,都会调用这个回调。在回调中,我们可以对当前注册的类型进行判断(一般通过接口、特性等),如果满足我们的条件,就添加一个拦截器。

ABP - 依赖注入(2)

ABP - 依赖注入(2)

ABP - 依赖注入(2)

在我们调用useAutofac()时,内部会调用UseServiceProviderFactory()创建了一个AbpAutofacServiceProviderFactory,这是实现了微软IServiceProviderFactory<>接口的一个容器工厂,任何容器提供了这个接口实现类,并且按照约定提供了ContainerBuilder,都可以作为.net core中的依赖注入容器。

在.net Core应用程序启动的时候会调用IServiceProviderFactory<>接口的CreateBuilder(IServiceCollection services)方法,我们注册的回调函数就是在这个时候执行的。遍历每一个类,在多个回调中进行执行,符合条件的都会添加一个拦截器。

ABP - 依赖注入(2)

ABP - 依赖注入(2)

最终是向autofac容器注册拦截器。

拦截器类需要实现IAbpInterceptor接口,或者继承AbpInterceptor,实现其中的InterceptAsync方法。如果对某一个类配置了拦截器,实际上它在注册到容器中时,abp会基于拦截器动态生成一个代理类,再将代理类注册到autofac中。

动态代理是基于Castle实现的。abp继承了Castle动态代理的AsyncDeterminationInterceptor,通过继承了AsyncInterceptorBase使用适配器模式将拦截器进行包装,并且将方法执行的参数进行封装传递到我们定义的拦截器中。

ABP - 依赖注入(2)

ABP - 依赖注入(2)

执行被拦截的类的方法时,实际上通过代理类在执行InterceptAsync()方法,这类似于传统过滤器的效果,所以通过这种方式,我们可以在方法执行前后添加一些和业务无关的全局的操作,即一些横切关注点。



ABP 系列总结:

目录:ABP 系列总结
上一篇:ABP - 依赖注入(1)
下一篇:ABP - 缓存模块(1)文章来源地址https://www.toymoban.com/news/detail-464503.html

到了这里,关于ABP - 依赖注入(2)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Springboot依赖注入Bean的三种方式,final+构造器注入Bean

    @Autowired注解的一大使用场景就是Field Injection。 通过Java的反射机制实现,所以private的成员也可以被注入具体的对象 优点 代码少,简洁明了。 新增依赖十分方便,不需要修改原有代码 缺点 容易出现空指针异常。Field 注入允许构建对象实例时依赖的对象为空,导致空指针异常

    2024年02月02日
    浏览(48)
  • VS依赖注入(DI)构造函数自动生成局部私有变量

    依赖注入(DI)在开发中既是常见的也是必需的技术。它帮助我们优化了代码结构,使得应用更加灵活、易于扩展,同时也降低了各个模块之间的耦合度,更容易进行单元测试,提高了编码效率和质量。我们经常会先定义局部变量,再在构造函数中使用,每次都要这样去编写耗时

    2024年02月11日
    浏览(45)
  • Spring依赖注入之setter注入与构造器注入以及applicationContext.xml配置文件特殊值处理

    依赖注入之setter注入 在管理bean对象的组件的时候同时给他赋值,就是setter注入,通过setter注入,可以将某些依赖项标记为可选的,因为它们不是在构造对象时立即需要的。这种方式可以减少构造函数的参数数量,使得类的构造函数更加简洁。 注:既然是setter注入,则对象的

    2024年01月25日
    浏览(46)
  • C#通过反射方法实现依赖注入

            看了很多依赖注入的插件,有时候一直在想,是不是都需要定义一个容器来绑定依赖注入的动态库,难道就不能按需注入?我这里的诉求其实很简单,希望注入的实体,在项目中没有任何一个地方是需要强引用的。         这里以切换关系数据库为例子。我在

    2024年02月09日
    浏览(36)
  • spring如何进行依赖注入,通过set方法把Dao注入到serves

    你在service层后面方法的这些:   最后我们执行一下 :  什么叫做依赖注入,serve应该于Dao的注入我就通过配置文件在容器中注把他注给他: 配置文件:  依赖注入有个简单方法,把properties那个子标签:  就是把这个子标签给省掉他: 1、如何引入,首先打开配置文件: 当我

    2024年02月12日
    浏览(36)
  • 使用 @Autowired 依赖注入时警告不建议使用字段注入

    在 Spring 中注入依赖时有 字段注入 、 构造器注入 、S etter 方法注入 三种注入方式。 无法注入 final 字段 在 Spring 2.5 中引入了 @Autowired 注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。在成员变量上使用 @Autowired 注解可以进行字段注入,如下:

    2024年02月05日
    浏览(42)
  • netCore使用依赖注入

    依赖注入是一种常用的设计模式,用于解耦组件之间的依赖关系。通过依赖注入,我们可以将一个组件所依赖的其他组件的创建和管理工作交给容器来完成,从而实现组件之间的解耦和灵活性 .NET Core提供了内置的依赖注入容器,使我们能够轻松地实现依赖注入。下面是使用依

    2024年02月16日
    浏览(35)
  • WPF使用依赖注入

    现在依赖注入在.Net里面已经普及,自己常写一些简单的demo倒是无所谓,但偶尔写一点正式的工程,也免不了要使用一下,于是总结了一下在WPF里面使用依赖注入。 在写简单Demo时候,通常是在MainWindow的构造函数里面直接做初始化,各种变量也都丢在MainWindow类里面。在使用依

    2024年02月11日
    浏览(34)
  • 依赖注入 与 Wire 的使用

    控制反转(Inversion of Control,缩写为IoC),是 面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度 。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)。依赖注入是生成灵活和松散耦合代码的标准技术,通过明确地向组件提供它们所需要的所有

    2024年03月11日
    浏览(37)
  • .NET使用依赖注入,控制反转

    .NET 支持依赖项注入 (DI) 软件设计模式,这是一种在类及其依赖项之间实现 控制 (IoC) 的反转 的技术 避免有状态的、静态类和成员。 通过将应用设计为改用单一实例服务,避免创建全局状态。 避免在服务中直接实例化依赖类。 直接实例化会将代码耦合到特定实现。 不在服务

    2023年04月16日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包