zoukankan      html  css  js  c++  java
  • 给微软的依赖注入框架写一些扩展方法

    给微软的依赖注入框架写一些扩展方法

    Intro

    现在在项目里大多都是直接使用微软的依赖注入框架,而微软的注入方式比较简单,不如 AutoFac 使用起来灵活,于是想给微软的依赖注入增加一些扩展,使得可以像AutoFac 一样比较灵活的注册服务

    Extensions

    RegisterTypeAsImplementedInterface

    将类型注册为其实现的接口,比如 pubic class UserService:IUserService,IUserRepository{}

    注册 UserServiceIUserServiceIUserRepository

    等效于:

    services.AddSingleton<IUserService, UserService>();
    services.AddSingleton<IUserRepository, UserService>();
    

    实现代码:

    /// <summary>
    /// RegisterTypeAsImplementedInterfaces
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="type">type</param>
    /// <param name="serviceLifetime">service lifetime</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterTypeAsImplementedInterfaces(this IServiceCollection services, Type type, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)
    {
        if (type != null)
        {
            foreach (var interfaceType in type.GetImplementedInterfaces())
            {
                services.Add(new ServiceDescriptor(interfaceType, type, serviceLifetime));
            }
        }
        return services;
    }
    

    RegisterAssemblyTypesAsImplementedInterface

    在上面的基础上,加载指定程序集中的类型(不指定程序集则使用当前应用程序域中所有程序集),可以通过 typesFilter 来过滤要注册的类型

    使用示例:

    services.RegisterAssemblyTypesAsImplementedInterface(t => !t.IsAbstract && t.IsClass && t.IsAssignableTo<IEventHandler>(), typeof(NoticeViewEventHandler).Assembly);
    

    实现源码:

    
    /// <summary>
    /// RegisterTypeAsImplementedInterfaces
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyTypesAsImplementedInterfaces(this IServiceCollection services,
        params Assembly[] assemblies)
        => RegisterAssemblyTypesAsImplementedInterfaces(services, typesFilter: null, ServiceLifetime.Singleton, assemblies);
    
    /// <summary>
    /// RegisterTypeAsImplementedInterfaces
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="serviceLifetime">service lifetime</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyTypesAsImplementedInterfaces(this IServiceCollection services,
        ServiceLifetime serviceLifetime, params Assembly[] assemblies)
        => RegisterAssemblyTypesAsImplementedInterfaces(services, typesFilter: null, serviceLifetime, assemblies);
    
    /// <summary>
    /// RegisterTypeAsImplementedInterfaces, singleton by default
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="typesFilter">filter types to register</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyTypesAsImplementedInterfaces(this IServiceCollection services, Func<Type, bool> typesFilter, params Assembly[] assemblies)
        => RegisterAssemblyTypesAsImplementedInterfaces(services, typesFilter: typesFilter, ServiceLifetime.Singleton, assemblies);
    
    /// <summary>
    /// RegisterTypeAsImplementedInterfaces
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="typesFilter">filter types to register</param>
    /// <param name="serviceLifetime">service lifetime</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyTypesAsImplementedInterfaces(this IServiceCollection services, Func<Type, bool> typesFilter, ServiceLifetime serviceLifetime, params Assembly[] assemblies)
    {
        if (assemblies == null || assemblies.Length == 0)
        {
            assemblies = ReflectHelper.GetAssemblies();
        }
    
        var types = assemblies
            .Select(assembly => assembly.GetExportedTypes())
            .SelectMany(t => t);
        if (typesFilter != null)
        {
            types = types.Where(typesFilter);
        }
    
        foreach (var type in types)
        {
            foreach (var implementedInterface in type.GetImplementedInterfaces())
            {
                services.Add(new ServiceDescriptor(implementedInterface, type, serviceLifetime));
            }
        }
    
        return services;
    }
    

    RegisterAssemblyTypes

    注册类型,这相当于 AutoFacRegisterAssemblyTypes().AsSelf()

    services.RegisterAssemblyTypes(t => !t.IsAbstract && t.IsClass && t.IsAssignableTo<IEventHandler>(), typeof(NoticeViewEventHandler).Assembly);
    

    实现源码:

    /// <summary>
    /// RegisterAssemblyTypes
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyTypes(this IServiceCollection services, params Assembly[] assemblies)
        => RegisterAssemblyTypes(services, null, ServiceLifetime.Singleton, assemblies);
    
    /// <summary>
    /// RegisterAssemblyTypes
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="serviceLifetime">service lifetime</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyTypes(this IServiceCollection services,
        ServiceLifetime serviceLifetime, params Assembly[] assemblies)
        => RegisterAssemblyTypes(services, null, serviceLifetime, assemblies);
    
    /// <summary>
    /// RegisterAssemblyTypes
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="typesFilter">filter types to register</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyTypes(this IServiceCollection services,
        Func<Type, bool> typesFilter, params Assembly[] assemblies)
        => RegisterAssemblyTypes(services, typesFilter, ServiceLifetime.Singleton, assemblies);
    
    /// <summary>
    /// RegisterAssemblyTypes
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="typesFilter">filter types to register</param>
    /// <param name="serviceLifetime">service lifetime</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyTypes(this IServiceCollection services, Func<Type, bool> typesFilter, ServiceLifetime serviceLifetime, params Assembly[] assemblies)
    {
        if (assemblies == null || assemblies.Length == 0)
        {
            assemblies = ReflectHelper.GetAssemblies();
        }
    
        var types = assemblies
            .Select(assembly => assembly.GetExportedTypes())
            .SelectMany(t => t);
        if (typesFilter != null)
        {
            types = types.Where(typesFilter);
        }
    
        foreach (var type in types)
        {
            services.Add(new ServiceDescriptor(type, type, serviceLifetime));
        }
    
        return services;
    }
    

    ServiceModule

    在 AutoFac 中有一个 Module 的概念可以让我们更方便的注册,一般可以在一个 Module 里注册需要服务注册的服务,这样注册的好处在于容易做插件化,新的插件需要注册什么样的服务,外界并不知道,如果用 Module 的注册方式,我只需要调用插件中的 Module 就可以注册所需要的服务了

    IServiceModule

    类似于 AutoFac 中的 Module,我们也可以定义一个 IServiceModule,定义一个 ConfigueServices(IServiceCollection services) 的方法用来注册服务

    public interface IServiceModule
    {
        void ConfigureServices(IServiceCollection services);
    }
    

    ServiceModule Demo

    public class BusinessServiceModule : IServiceModule
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddEFRepository();
            services.AddBLL();
            services.TryAddScoped<ReservationHelper>();
            services.TryAddSingleton<CaptchaVerifyHelper>();
            services.TryAddSingleton<OperLogHelper>();
        }
    }
    

    RegisterAssemblyModules

    上面我们定义了一个 Module,下面来定义一个扩展方法来注册 module 中的服务信息

    使用示例:

    // load service modules
    services.RegisterAssemblyModules(pluginAssemblies);
    

    实现源码:

    /// <summary>
    /// RegisterAssemblyModules
    /// </summary>
    /// <param name="services">services</param>
    /// <param name="assemblies">assemblies</param>
    /// <returns>services</returns>
    public static IServiceCollection RegisterAssemblyModules(
        [NotNull] this IServiceCollection services, params Assembly[] assemblies)
    {
        if (assemblies == null || assemblies.Length == 0)
        {
            assemblies = ReflectHelper.GetAssemblies();
        }
        foreach (var type in assemblies.SelectMany(ass => ass.GetTypes())
            .Where(t => t.IsClass && !t.IsAbstract && typeof(IServiceModule).IsAssignableFrom(t))
        )
        {
            try
            {
                if (Activator.CreateInstance(type) is IServiceModule module)
                {
                    module.ConfigureServices(services);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    
        return services;
    }
    

    Reference

  • 相关阅读:
    ios framework 使用图片资源
    XCode 6.4 Alcatraz 安装的插件不可用
    prefix pch 中引用cocoapods 中的头文件失败
    Xcode 6添加模板无效
    获取当前日期是星期几
    玩转iOS开发:《使用系统自带的UIActivityViewController和UIActivity进行内容分享》
    玩转iOS开发:《iOS设计模式 — 代理模式》
    玩转iOS开发:《iOS设计模式 — 单例模式》
    iOS开发技巧-Swift版本: 3.Storyboard传参小技巧
    UIKit应用
  • 原文地址:https://www.cnblogs.com/weihanli/p/12362576.html
Copyright © 2011-2022 走看看