您当前的位置: 首页 >  .net

寒冰屋

暂无认证

  • 4浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

使用Service Installer在.NET Core中配置依赖注入而无需任何代码

寒冰屋 发布时间:2020-04-27 22:33:25 ,浏览量:4

目录

介绍

描述

在本文中,我将解释如何使用一个名为IServiceInstaller的接口,您可以在配置依赖注入时使用它,然后使用简单的反射代码自动读取它。

介绍

这是我们配置IServiceInstaller接口的方式:

public interface IServiceInstaller
{
   void InstallServices(IServiceCollection services, 
                        AppSettings appSettings, Assembly startupProjectAssembly);
}
描述

“appSettings”参数是一个类,其中包含所有“appsettings.json”文件配置值。您您确实可以使用IConfiguration并将对象传递给StartUp类。当您想在API层以外的另一层中实现这些文件时,使用“startupProjectAssembly”参数。

然后这就是我们使用反射来实现ConfigureServices方法的扩展方法的方式:

public static class ServiceInstallerExtensions
    {
        public static void InstallServicesInAssemblies
               (this IServiceCollection services, AppSettings appSettings)
        {
            var startupProjectAssembly = Assembly.GetCallingAssembly();
            var assemblies = new[] { startupProjectAssembly, Assembly.GetExecutingAssembly() };
            var installers = assemblies.SelectMany(a => a.GetExportedTypes())
                .Where(c => c.IsClass && !c.IsAbstract 
                && c.IsPublic && typeof(IServiceInstaller).IsAssignableFrom(c))
                .Select(Activator.CreateInstance).Cast().ToList();
            installers.ForEach(i => i.InstallServices
                              (services, appSettings, startupProjectAssembly));
        }
    }

最终,在添加所有服务之后,我们实现如下ConfigureServices方法:

public void ConfigureServices(IServiceCollection services)
        {
            //* HttpContextAccessor
            // services.AddHttpContextAccessor();
            //* Controllers
            services.AddControllers(options => { options.Filters.Add(new AuthorizeFilter()); })
                .AddNewtonsoftJson();

            //* Installers
            services.InstallServicesInAssemblies(_appSettings);
        }

完成了。现在,所有IServiceInstaller实现的服务将自动在ConfigureServices中注册。

我们使用AutoRegisterDi包自动注册DI服务。现在我们建立一个名为:

 

public class RegisterServicesUsingAutoRegisterDiInstaller : IServiceInstaller
    {
        public void InstallServices
        (IServiceCollection services, AppSettings appSettings, Assembly startupProjectAssembly)
        {
            var dataAssembly = typeof(SomeRepository).Assembly;
            var serviceAssembly = typeof(SomeService).Assembly;
            var webFrameworkAssembly = Assembly.GetExecutingAssembly();
            var startupAssembly = startupProjectAssembly;
            var assembliesToScan = new[] 
            { dataAssembly, serviceAssembly, webFrameworkAssembly, startupAssembly };

            #region Generic Type Dependencies
            services.AddScoped(typeof(IRepository), typeof(Repository));
            #endregion

            #region Scoped Dependency Interface
            services.RegisterAssemblyPublicNonGenericClasses(assembliesToScan)
                .Where(c => c.GetInterfaces().Contains(typeof(IScopedDependency)))
                .AsPublicImplementedInterfaces(ServiceLifetime.Scoped);
            #endregion

            #region Singleton Dependency Interface
            services.RegisterAssemblyPublicNonGenericClasses(assembliesToScan)
                .Where(c => c.GetInterfaces().Contains(typeof(ISingletonDependency)))
                .AsPublicImplementedInterfaces(ServiceLifetime.Singleton);
            #endregion

            #region Transient Dependency Interface
            services.RegisterAssemblyPublicNonGenericClasses(assembliesToScan)
                .Where(c => c.GetInterfaces().Contains(typeof(ITransientDependency)))
                .AsPublicImplementedInterfaces(); // Default is Transient
            #endregion

            #region Register DIs By Name
            services.RegisterAssemblyPublicNonGenericClasses(dataAssembly)
                .Where(c => c.Name.EndsWith("Repository")
                            && !c.GetInterfaces().Contains(typeof(ITransientDependency))
                            && !c.GetInterfaces().Contains(typeof(IScopedDependency))
                            && !c.GetInterfaces().Contains(typeof(ISingletonDependency)))
                .AsPublicImplementedInterfaces(ServiceLifetime.Scoped);

            services.RegisterAssemblyPublicNonGenericClasses(serviceAssembly)
                .Where(c => c.Name.EndsWith("Service")
                            && !c.GetInterfaces().Contains(typeof(ITransientDependency))
                            && !c.GetInterfaces().Contains(typeof(IScopedDependency))
                            && !c.GetInterfaces().Contains(typeof(ISingletonDependency)))
                .AsPublicImplementedInterfaces();
            #endregion
        }
    }

 

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.1267s