如何根据构建配置配置简单注入器

How to configure Simple Injector depending on build configuration

我希望能够为每个开发人员配置不同的简单注入器(例如用于原型设计)。 当然,默认配置应该是硬编码的。

我以前使用过 Unity,我可以用 XML 配置文件覆盖硬编码注册。此配置文件不受源代码控制,因此其他开发人员可以使用他们的自定义注册覆盖硬编码注册,而不会干扰其他人。

开发人员应该不需要将他们的配置提交到源代码管理。

Simple Injector 支持这样的场景吗? 这种情况有什么最佳做法吗? 这是否有意义,或者是否有更好的方法来实现我想要的?

Simple Injector 的设计决策之一是不支持开箱即用的基于 XML 的配置。此决定描述为 here,但可概括为:

XML based configuration is brittle, error prone and always provides a subset of what you can achieve with code based configuration. General consensus is to use code based configuration as much as possible and only fall back to file based configuration for the parts of the configuration that really need to be customizable after deployment. These are normally just a few registrations since the majority of changes would still require developer interaction (write unit tests or recompile for instance). Even for those few lines that do need to be configurable, it’s a bad idea to require the fully qualified type name in a configuration file. A configuration switch (true/false or simple enum) is more than enough. You can read the configured value in your code based configuration, this allows you to keep the type names in your code. This allows you to refactor easily, gives you compile-time support and is much more friendly to the person having to change this configuration file.

但这并不能完全满足您的要求,因为您不想"customizable after deployment"。相反,您想针对每个开发人员进行自定义。

对于这种特殊情况,您不应该退回到基于 XML 的配置 IMO。正如您可以使用 .gitignore 排除 xml 文件一样,您可以对基于代码的配置文件执行相同的操作,开发人员可以更改这些配置文件,并将与应用程序的其余部分一起编译。这是一个例子:

// Global.cs
public void Application_Start() {
    var container = new Container();

    // Default configuration here

    container.Options.AllowOverridingRegistrations = true;
    DeveloperOverrides.ApplyOverrides(container);
    container.Options.AllowOverridingRegistrations = false;

    DependencyResolver.Current = new SimpleInjectorDependencyResolver(container);
}

// DeveloperOverrides.cs
public static class DeveloperOverrides {
    public static void ApplyOverrides(Container container) {
    }
}

这两个文件可以签入,其中DeveloperOverrides.ApplyOverrides方法留空。之后,将 DeveloperOverrides.cs 的排除项添加到 .gitignore 文件中。

在此之后,开发人员可以添加自己的覆盖,这些覆盖由编译器检查,但永远不会签入源代码管理:

// DeveloperOverrides.cs
public static class DeveloperOverrides {
    public static void ApplyOverrides(Container container) {
        container.Register<IMailSender, FakeMailSender>(Lifestyle.Singleton);
    }
}