gpt4 book ai didi

c# - C# 中具有嵌套通用约束的 Fluent API 设计

转载 作者:行者123 更新时间:2023-11-30 17:28:23 25 4
gpt4 key购买 nike

我目前正在实现一个供内部使用的 IoC 设置 API(深受 Autofac 模块系统的启发)。

我们有 Module 可以通过强类型配置进行配置,并且我希望一个模块能够需要其他模块,这样我就可以拥有一个类似于“组合根”的主模块,它将引导整个应用程序。

public interface IModule<TConfig>
{
TConfig Config { get; }

void Load(ContainerBuilder builder);

void LoadExtraModules(ModuleRegister register);
}

我目前正在设计 ModuleRegister 类。我希望能够做的与此类似:

public class MyModule : ModuleBase<ApplicationConfiguration>
{
public void LoadExtraModules(ModuleRegister register)
{
register.Module<SqlModule>().WithConfig(new SqlConfiguration() { ... });
}
}

public class SqlModule : ModuleBase<SqlConfiguration>
{
public void Load(ContainerBuilder builder)
{
// configuration code.
}
}

我想要的是让 Intellisense 以某种方式建议 SqlConfigurationSqlModule 的正确配置类型,但我没有做到这一点:我想表达类似于

的类型参数
// ... inside an helper ExtraModulesRegister<TModule> class

public void WithConfig<TConfig>(TConfig configuration)
where TModule : IModule<TConfig>
{
...
}

但显然我只能表达对 TConfig 的约束,不能表达对 TModule 的约束。

我找到的唯一解决方案是使用如下扩展方法:

    public static void WithConfig<TConfig, TModule>(this ExtraModulesRegister<TModule> register,
TConfig configuration)
where TModule : IModule<TConfig>, new()
{
register.LoadModule<TModule, TConfig>(configuration);
}

所以我可以表达两种类型约束,其中一种是针对已定义的泛型参数 TModule

我(几乎)可以自由地改变一切的设计。

如有任何建议,我们将不胜感激。

最佳答案

我尝试用 ExtraModulesRegister 的两个参数进行参数化类本身:

public class ExtraModulesRegister<TModule, TConfig> wher TModule : IModule<TConfig> {

void WithConfig(TConfig config) {

}

}

但是现在您可能需要一些技巧让 TConfigSqlConfig 推断出,所以你不需要传递这两个参数。我想像 helper type 这样的东西可以提供帮助,所以你调用 register.Module(X<SqlModule>())所以通过传递类似 X<TModule> 的参数使 Module()方法推断两者,TModuleTConfig .

public ExtraModulesRegister<TModule, TConfig> Module<TModule, TConfig>(X<TModule> module) where TModule : IModule<TConfig> {
...
}

class X<T> {}

public static X<T> X<T>() {
return new X<T>();
}

不幸的是,C# 似乎无法推断类型。在 Java 中,相同的模式起作用,编译器可以从一个参数推断出这两种类型并定义它们之间的关系。

编辑:这在 C# 中有效,但它可能不是您想要的语法:

public class ExtraModulesRegister<TConfig> {
void WithConfig(TConfig config) {}
}

// Module method
public ExtraModulesRegister<TConfig> Module<TConfig>(IModule<TConfig> fakeModule) {
Return new ExtraModulesRegister<TConfig>();
}

// Usage
register.Module(default(SqlModule)).WithConfig(new SqlConfig());

关于c# - C# 中具有嵌套通用约束的 Fluent API 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52929908/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com