温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

asp.net core中的IOC是什么

发布时间:2021-12-06 14:11:15 来源:亿速云 阅读:244 作者:iii 栏目:大数据

这篇文章主要介绍“asp.net core中的IOC是什么”,在日常操作中,相信很多人在asp.net core中的IOC是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”asp.net core中的IOC是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1. IOC和DI

先来给大家解释几个概念,IOC全称Inversion of Control,翻译过来就是控制反转,是面向对象编程的一种设计原则,用来降低代码之间的耦合度。所谓的控制反转简单来讲就是将类中属性或者其他参数的初始化交给其他方处理,而不是直接使用构造函数。

public class Demo1
{
}

public class Demo2
{
   public Demo1 demo;
}
 

对于以上简单示例代码中,在Demo2类中持有了一个Demo1的实例。如果按照之前的情况来讲,我们会通过以下方法为demo赋值:

// 方法一
public Demo1 demo = new Demo1();
// 方法二
public Demo2()
{
   demo = new Demo1();
}
 

这时候,如果Demo1变成下面的样子:

public class Demo1
{
   public Demo1(Demo3 demo3)
   {
       // 隐藏
   }
}
public class Demo3
{
}
 

那么,如果Demo2 没有持有一个Demo3的实例对象,这时候创建Demo1的时候就需要额外构造一个Demo3。如果Demo3需要持有另外一个类的对象,那么Demo2中就需要多创建一个对象。最后就会发现这样就陷入了一个构造“地狱”(我发明的词,指这种为了一个对象却得构造一大堆其他类型的对象)。

实际上,对于Demo2并不关心Demo1的实例对象是如何获取的,甚至都不关心它是不是Demo1的子类或者接口实现类。我在示例中使用了类,但这里可以同步替换成Interface,替换之后,Demo2在调用Demo1的时候,还需要知道Demo1有实现类,以及实现类的信息。

为了解决这个问题,一些高明的程序员们提出了将对象的创建这一过程交给第三方去操作,而不是调用类来创建。于是乎,上述代码就变成了:

public class Demo2
{
   public Demo1 Demo {get;set;}
   public Demo2(Demo1 demo)
   {
       Demo = demo;
   }
}
 

似乎并没有什么变化?对于Demo2来说,Demo2从此不再负责Demo1的创建,这个步骤交由Demo2的调用方去创建,Demo2从此从负责维护Demo1这个对象的大麻烦中解脱了。

但实际上构造地狱的问题还是没有解决,只不过是通过IOC的设计将这一步后移了。这时候,那些大神们想了想,不如开发一个框架这些实体对象吧。所以就出现了很多IOC框架:AutoFac、Sping.net、Unity等。

说到IOC就不得不提一下DI(Dependency Injection)依赖注入。所谓的依赖注入就是属性对应实例通过构造函数或者使用属性由第三方进行赋值。也就是最后Demo2的示例代码中的写法。

早期IOC和DI是指一种技术,后来开始确定这是不同的描述。IOC描述的是一种设计模式,而DI是一种行为。

 

2. 使用asp.net core的默认IOC

在之前的ASP.NET 框架中,微软并没有提供默认的IOC支持。在最新的asp.net core中微软提供了一套IOC支持,该支持在命名空间:

Microsoft.Extensions.DependencyInjection
 

里,在代码中引用即可。

主要通过以下几组方法实现:

public static IServiceCollection AddScoped<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddSingleton<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddTransient<TService>(this IServiceCollection services) where TService : class;
 

这里只列出了这三组方法的一种重载版本。

这三组方法分别代表三种生命周期:

  • AddScored 表示对象的生命周期为整个Request请求

  • AddTransient 表示每次从服务容器进行请求时创建的,适合轻量级、 无状态的服务

  • AddSingleton 表示该对象在第一次从服务容器请求后获取,之后就不会再次初始化了

这里每组方法只介绍了一个版本,但实际上每个方法都有以下几个版本:

public static IServiceCollection AddXXX<TService>(this IServiceCollection services) where TService : class;
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType, Type implementationType);
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType, Func<IServiceProvider, object> implementationFactory);
public static IServiceCollection AddXXX<TService, TImplementation>(this IServiceCollection services)
           where TService : class
           where TImplementation : class, TService;
public static IServiceCollection AddXXX(this IServiceCollection services, Type serviceType);
public static IServiceCollection AddXXX<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class;
public static IServiceCollection AddXXX<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
           where TService : class
           where TImplementation : class, TService;
 

其中:implementationFactory 表示通过一个Provider实现TService/TImplementation 的工厂方法。当方法指定了泛型的时候,会自动依据泛型参数获取要注入的类型信息,如果没有使用泛型则必须手动传入参数类型。

asp.net core如果使用依赖注入的话,需要在Startup方法中设置,具体内容可以参照以下:

public void ConfigureServices(IServiceCollection services)
{
   //省略其他代码
   services.AddScoped<ISysUserAuthRepository,SysUserAuthRepository>();
}
 

asp.net core 为DbContext提供了不同的IOC支持,AddDbContext:

public static IServiceCollection AddDbContext<TContext>(
     this IServiceCollection serviceCollection,
     Action<DbContextOptionsBuilder> optionsAction = null,
     ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
     ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
     where TContext : DbContext;
 

使用方法如下:

services.AddDbContext<DefaultContext>();
   

3. AutoFac 使用

理论上,asp.net core的IOC已经足够好了,但是依旧原谅我的贪婪。如果有二三百个业务类需要我来设置的话,我宁愿不使用IOC。因为那配置起来就是一场极其痛苦的过程。不过,可喜可贺的是AutoFac可以让我免受这部分的困扰。

这里简单介绍一下如何使用AutoFac作为IOC管理:

cd Web  # 切换目录到Web项目
dotnet package add Autofac.Extensions.DependencyInjection # 添加 AutoFac的引用
 

因为asp.net core 版本3更改了一些逻辑,AutoFac的引用方式发生了改变,现在不介绍之前版本的内容,以3为主。使用AutoFac需要先在 Program类里设置以下代码:

public static IHostBuilder CreateHostBuilder(string[] args) =>
           Host.CreateDefaultBuilder(args)
           .UseServiceProviderFactory(new AutofacServiceProviderFactory()) // 添加这行代码
           .ConfigureWebHostDefaults(webBuilder =>
           {
               webBuilder.UseStartup<Startup>();
           });
 

在Program类里启用AutoFac的一个Service提供工厂类。然后在Startup类里添加如下方法:

public void ConfigureContainer(ContainerBuilder builder)
{
   builder.RegisterType<DefaultContext>().As<DbContext>()
               .WithParameter("connectStr","Data Source=./demo.db")
               .InstancePerLifetimeScope();


   builder.RegisterAssemblyTypes(Assembly.Load("Web"))
       .Where(t => t.BaseType.FullName.Contains("Filter"))
       .AsSelf();

   builder.RegisterAssemblyTypes(Assembly.Load("Domain"),
                   Assembly.Load("Domain.Implements"), Assembly.Load("Service"), Assembly.Load("Service.Implements"))
               .AsSelf()
               .AsImplementedInterfaces()
               .InstancePerLifetimeScope()
               .PropertiesAutowired();
}
 

修改:

public void ConfigureServices(IServiceCollection services)
{
   services.AddControllersWithViews(options =>
           {
               options.Filters.Add<UnitOfWorkFilterAttribute>();
           }).AddControllersAsServices();// 这行新增
   // 省略其他
}

到此,关于“asp.net core中的IOC是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI