【问题标题】:How to Split ConfigureServices method (of Startup) into multiple files如何将 ConfigureServices 方法(启动)拆分为多个文件
【发布时间】:2018-06-17 15:41:13
【问题描述】:

关注点分离 (SoC)

在 ConfigureServices 中注册的依赖指令(启动类的方法)由不同的 DI 组成,如 Repository、Fluent Validations 等。

我将如何将 DI 注册分成单独的文件(如下所示)

【问题讨论】:

  • 在同一个项目或不同项目中分开文件?可以创建扩展方法
  • @Nkosi 它在同一个项目中。当然我可以使用扩展,但是有没有像参考委托这样的替代方法..
  • 扩展方法是减少Startup类中最常见的方法。
  • 你应该使用extract method重构。

标签: c# dependency-injection repository-pattern fluentvalidation separation-of-concerns


【解决方案1】:

创建一个扩展方法来保存您想要的任何其他配置

public static class MyExtensions {
    public static IServiceCollection AddFluentValidation(this IServiceCollection services) {

        //...add services

        return services;
    }
}

然后在ConfigureServices中调用Startup

public void ConfigureServices(IServiceCollection services) {

    //...

    services.AddFluentValidation();
    services.AddRepository();

    //...

}

框架和第 3 方扩展通常使用扩展方法来填充服务集合。

【讨论】:

    【解决方案2】:

    startup.cs

    public class Startup
    {
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMyScoped();
                services.AddMyTransient();
            }
    }
    

    AddScopedExtension.cs

    public static class AddScopedExtension
    {
        public static IServiceCollection AddMyScoped(this IServiceCollection serviceCollection)
        {
            // TODO : Add your Scoped Objects here
            return serviceCollection;
        }
    }
    

    AddTransientExtension.cs

    public static class AddTransientExtension
    {
        public static IServiceCollection AddMyTransient(this IServiceCollection serviceCollection)
        {
            // TODO : Add your Scoped Objects here
            return serviceCollection;
        }
    }
    

    【讨论】:

      【解决方案3】:

      你好,你可以试试这个方法

      添加扩展方法

       public static class SlightDIModuleConfigExtension
      {
           public static IWebHostBuilder UseSlightDIModuleconfig(this IWebHostBuilder webHostBuilder)
          {
      
              return webHostBuilder.ConfigureServices(services =>
              {
                  foreach (Type type in Assembly.GetEntryAssembly()
                   .GetTypes()
                   .Where(myType => myType.IsSubclassOf(typeof(SlightModuleConfigure))))
                  {
                      var instance = Activator.CreateInstance(type);
                      MethodInfo mi = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault();
                      mi.Invoke(instance, new object[] { services });
                  }
              });
          }
      }
      

      添加抽象类

      public abstract class SlightModuleConfigure
      {
          protected virtual void Load(IServiceCollection services) { }
      }
      

      如何使用

      在 Program.cs 中添加 UseSlightDIModuleconfig()

       public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
              WebHost.CreateDefaultBuilder(args)
                 .UseStartup<Startup>()
                .UseSlightDIModuleconfig(); //add this .
      

      像这样添加类继承SlightModuleConfigure

      public class PayModuleConfig : SlightModuleConfigure
      {
          protected override void Load(IServiceCollection services)
          {
                services.AddTransient<Ipay, PayImp>();
          }
      }
      

      可以参考SlightDIConfigure

      【讨论】:

        【解决方案4】:

        Partial class - 只是另一种方式!

        // Startup.cs
        public partial class Startup {
            public void ConfigureServices(IServiceCollection services) {
                ConfigureScopedServices(services);
                ConfigureTransientServices(services);
            }
        }
        
        // ScopedServices.cs
        public partial class Startup {
            private static void ConfigureScopedServices(IServiceCollection services) {
                Console.WriteLine("Scoped");
            }
        }
        
        // TransientServices.cs
        public partial class Startup {
            private static void ConfigureTransientServices(IServiceCollection services) {
                Console.WriteLine("Transient");
            }
        }
        

        【讨论】:

        • 从未真正考虑过使用部分。
        • 你的意思是这是一种不好的做法吗?如果是这种情况,很高兴知道更多信息。
        • 不确定这是不好的做法还是只是个人喜好。我通常不使用部分代码,因为它会使代码更难维护。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多