此篇文章用来了解.NetCore的依赖注入方面的问题。
此篇文章参考了博客:全面理解依赖注入,这个大佬写的很好,我是在他的理解之上加入了自己的理解,我说的不明白的地方可以去看看和这个大佬写的。
1、什么是依赖,结合现实先想一想依赖这个词,就拿遥控器来举例:遥控器和电池他们就算依赖,遥控器必须依赖电池才能使用,电池就像一个接口,遥控器就像是实现了这个接口。有的人就想到了接口的概念,差不多就是这个意思,这个例子可能不太恰当,但是有助于你思考依赖这个概念。通俗讲:电池+遥控器才能运行,它们的关系叫做依赖。
2、什么是注入,在这里的注入其实是实现了IOC(控制反转),控制反转是一种思想,不是什么框架,也不是什么技术。传统程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象,而IOC是有专门一个容器来创建这些对象,即由IOC容器来控制对象的创建。谁控制谁?当然是IOC 容器控制了对象。控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
3、什么是容器,容器表面意思就是盛放东西的物品,其实也差不多,不过咱们的容器是用来获取实现需要注入的对象的。
4、什么是反转,有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转。而反转则是由容器来帮忙创建及注入依赖对象。为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转。哪些方面反转了?依赖对象的获取被反转了。
5、上面通俗的讲解了依赖注入,只是为了有一个概念,依赖注入的思想:将相互依赖对象的创建、协调工作交给容器去处理,每个对象只需要关注其自身的业务逻辑关系就可以了。在这样的角度上来看,获得依赖的对象的方式,进行了反转,变成了由容器控制对象如何获取外部资源(包括其他对象和文件资料等等)。
通俗点说许多应用都是通过彼此间的相互合作来实现业务逻辑的,如类A要调用类B的方法,以前我们都是在类A中,通过自身new一个类B,然后在调用类B的方法,现在我们把new类B的事情交给容器来做,在我们调用的时候,容器会为我们实例化。
希望小伙伴们看了我上面写的能有一些理解,假如有讲的不好的地方,请谅解,也可以在下面留言指出来,大家一起讨论进步。
1、基本信息
在.NET Core中DI的核心分为两个组件:IServiceCollection和 IServiceProvider。
IServiceCollection 负责注册
IServiceProvider 负责提供实例
IServiceCollection里面提供了三个注册方法:
1、AddSingleton 单例注册
整个应用程序生命周期以内只创建一个实例
2、AddTransient
每一次GetService都会创建一个新的实例,注册一个就会产生一个
3、AddScoped
在同一个请求域内只初始化一个实例
换句话来说:用Scope注册的对象,在同一个ServiceProvider的 Scope下相当于单例。
注:这三个注册方式的区别的代码实现就不贴了,感兴趣的参考开头的博客,或者自己摸索。
2、.NetCore应用程序中的应用
在项目中的Startup文件中你会看到跟下面一样的方法名,下面的代码就是注册的用法
public void ConfigureServices(IServiceCollection services)
{
//我这里仅供欣赏,并非需要注册三次。
services.AddSingleton(typeof(IUserRepository), typeof(UserRepository));
services.AddTransient (typeof(IUserRepository), typeof(UserRepository));
services.AddScoped(typeof(IUserRepository), typeof(UserRepository));
}
在你注入完成之后你每次新建控制器,就能通过控制器的构造函数传入该接口,无需再去重复new一个对象。
3 Controller中使用
public class UserController : Controller
{
private readonly IUserRepository _userRepository;//此处可以直接调用
//构造函数注入
public UserController(IUserRepository userRepository)
{
_userRepository = userRepository;
}
}
4、拓展
到这想必也对注入有了一定的了解,然后就会发现假如我们写100个接口想要注入的话你可能就要写100行代码,像这样:
public void ConfigureServices(IServiceCollection services)
{
//我这里仅供欣赏,并非需要注册三次。
//100个接口连续写100行这样的代码
services.AddScoped(typeof(IUserRepository), typeof(UserRepository));
services.AddScoped(typeof(IUserRepository), typeof(UserRepository));
services.AddScoped(typeof(IUserRepository), typeof(UserRepository));
}
这样不就提高了维护的成本,你看着也头疼。
在这里推荐几款NuGet程序包:
Autofac
Autofac.Extensions.DependencyInjection
.NetCore3.0以下的实现方式参考上面的那篇博客,我由于写的时候没注意选的3.1的.NetCore,所以今天就在这说一下3.0的Autofac注册使用方法,Autofac的注册方式基本不变,就是实现需要多一步。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//以前的Autofac都是在这个方法里注册3.0无法在此注册
}
//3.0之后需要新加一个方法 如下
public void ConfigureContainer(ContainerBuilder builder)
{
//泛型注入
builder
.RegisterGeneric(typeof(RepositoryBase<,>))
.As(typeof(IRepository<,>))
.PropertiesAutowired()
.InstancePerLifetimeScope();
//查找程序集中以Repository结尾的类型 反射注入
builder
.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
}
}
以上差不多就是本篇博客的主要内容了,关于Autofac的具体用法及详解后面会单独开一篇,现在需要用的话,建议百度23333,大家下次再见咯,有啥想说的建议留言哦,谢谢大家~