问题引入

  在ASP.NET Core - 依赖注入 <https://www.cnblogs.com/lex-wu/p/10739517.html>
这篇文章里面,我们知道了如何利用ASP.NET Core原生的容器来实现依赖注入的,那我们为什么要替换掉默认的 IoC容器呢?从ASP.NET Core -
依赖注入 <https://www.cnblogs.com/lex-wu/p/10739517.html>
这篇文章来看的话,默认的IoC容器对于一些小型的项目基本够用,它提供了基本的AddXXXX方法来绑定实例关系,但是对于大型项目来说,还是挺困难的,大型的项目需要的是通用的注册,不可能手动添加每个对象的解析关系,这才是我们面临的痛点。

  解决方案

  这里不打算详解Castle的内容,专注于如何使用Castle实现通用注册和替换掉原生的IoC容器。

  首先我们需要一个通用的注册类,是基于我们自定义规则来注册的,比如说在程序集中满足继承ITransientDependency
的话我们会给实现类注册为Transient的生命周期
/// <summary> /// 通过输入的程序集来注册满足约定的所有类 /// </summary> public class
BasicConventionalRegistrar {private readonly WindsorContainer _container = new
WindsorContainer();/// <summary> /// 注册程序集中满足约定的类 /// </summary> /// <param
name="assemblies"></param> /// <returns></returns> public WindsorContainer
RegisterAssembly(List<Assembly> assemblies) { foreach (var assembly in
assemblies) {//Transient _container.Register( Classes.FromAssembly(assembly)
.IncludeNonPublicTypes() .BasedOn<ITransientDependency>() .If(type => !
type.GetTypeInfo().IsGenericTypeDefinition) .WithService.Self()
.WithService.DefaultInterfaces() .LifestyleTransient() );//Singleton
_container.Register( Classes.FromAssembly(assembly) .IncludeNonPublicTypes()
.BasedOn<ISingletonDependency>() .If(type => !
type.GetTypeInfo().IsGenericTypeDefinition) .WithService.Self()
.WithService.DefaultInterfaces() .LifestyleSingleton() ); }return _container; }
}

   有个这个类,我们需要把各个程序集中满足条件的类注册进来,首先需要在NuGet下载Castle.Windsor.MsDependencyInjection包,并且在ConfigureServices方法中修改返回类型为IServiceProvider,让后通过
RegistBasicConventionalRegistrar把各个需要注册的程序集注册进来。

  这里需要非常注意的是,在ASP.NET Core - 依赖注入
<https://www.cnblogs.com/lex-wu/p/10739517.html>
这篇文章里面提到ConfigureServices是可以返回一个IServiceProvider对象的,这里是基于这个返回对象引入了第三方容器替换。
public IServiceProvider ConfigureServices(IServiceCollection services) {
services.AddMvc();var container = RegistBasicConventionalRegistrar();    //替换容器
return WindsorRegistrationHelper.CreateServiceProvider(container, services); }
//通用规则注册 private WindsorContainer RegistBasicConventionalRegistrar() { var list
=new List<Assembly>(); list.Add(Assembly.GetExecutingAssembly ());
list.Add(yourProjectAssembly); ...return
BasicConventionalRegistrar.RegisterAssembly(list); }
  这里主要是利用了WindsorRegistrationHelper这个类实现注册到Windsor
Castle容器中,这样在我们的service业务层,利用通用规则注册(这里有一点是需要注意的,就是我们的这个
RegistBasicConventionalRegistrar
方法是基于程序集注册的,个人建议在每个需要注册的程序集中添加一个标志该程序集的基类,比如说我会在Service这个程序集中添加一个IServiceBase接口,这样就可以通过typeof(IServiceBase).Assembly获取到这个程序集进而用来注册)
public interface IPostBlogService : ITransientDependency {
  Result Post(BlogDto dto); } public class PostBlogService : IPostBlogService
{ public Result Post(BlogDto dto)
  {
    //todo: post this blog
  } }
  在任何需要的地方通过构造方法注入(或属性注入)
[ApiController]
[Route("api/Blog")]
public class BlogController: Controller { public readonly IBlogService
_blogService;public BlogController(IBlogService blogService) { _blogService =
blogService; }   [HttpPost]public Result PostBlog(BlogDto dto) { return
_blogService.Post(dto); } }
   

  让我知道如果你有更好的想法或建议!

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信