zoukankan      html  css  js  c++  java
  • ASP.NET Core

      问题引入

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

      解决方案

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

      首先我们需要一个通用的注册类,是基于我们自定义规则来注册的,比如说在程序集中满足继承ITransientDependency的话我们会给实现类注册为Transient的生命周期,ISingletonDependency会给实现类注册为Singleton的生命周期。

        /// <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 - 依赖注入这篇文章里面提到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容器中,且核心方法RegistBasicConventionalRegistrar是基于程序集注册的。在正式的应用场景中,我们是非常可能需要把多个程序集都按约定来注册的,个人建议的做法是,在每个需要注册的程序集中添加一个标志该程序集的基类,比如说我会在Service这个程序集中添加一个IServiceBase接口,这样就可以通过typeof(IServiceBase).Assembly获取到这个程序集进而用来注册

      按约定进行继承

      在我们的service业务层(或者任何需要注册的地方),把需要注册的类继承通用注册接口(生命周期自己选择)

    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); } }

       这样就实现了完整的通用注册解析流程,在实际应用中,个人建议把这些通用解析方法放在基础设施模块,因为这样不仅本项目可以用,还可以把基础设施抽离出来作为基础框架,通过nuget使用版本控制作为公司所有项目的通用注册础框架。

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

    如果你觉得该文章还不错且有所收获,请右下角推荐一下,也可留下您的问题或建议,让我们共同进步。 原创博客请在转载时保留原文链接或者在文章开头加上本人博客地址!
  • 相关阅读:
    《新下级学》第七章第二节——冲突
    《新下级学》第七章序和第一节——微观互动
    《新下级学》第六章第七第八节(本章完)——下级软弱的根源等
    《新下级学》第六章第五第六节——下级的底线等
    《新下级学》第六章第三第四节——下级对平级的看法等
    《新下级学》第六章第二节——下级对自己的需求、能力和责任的看法
    《新下级学》第六章序、第一节——下级的思维特点及处境
    《新下级学》第四章、第五章——什么是“下级”
    《新下级学》第三章——新下级学的立场
    变电站GPS校时产品(GPS对时设备)在线监测技术
  • 原文地址:https://www.cnblogs.com/lex-wu/p/10604767.html
Copyright © 2011-2022 走看看