访问请求服务的泛型类型以进行参数构造

本文关键字:参数 请求 服务 泛型类型 访问 | 更新日期: 2023-09-27 18:37:03

我有一个强类型配置的服务协定:

public interface IConfigurationSource<TConfiguration> {
    TConfiguration Current { get; }
}

以及基于 YAML 文件的实现:

public class YamlFileConfigurationSource<TConfiguration> 
    : IConfigurationSource<TConfiguration> {
    public YamlFileConfigurationSource(string fileName) { }
    ...
}

现在,我正在尝试在 Autofac 中注册实现,以便可以根据所请求服务的泛型类型构造 fileName 参数。因此,当客户端请求YamlFileConfigurationSource<MyCustomConfigurationModel>可以提供像MyCustomConfigurationModel.config这样的路径时。

我已经尝试过ContainerBuilder.RegisterGeneric().WithConstructor()和委托工厂,但是我不知何故无法看到如何在注册期间访问泛型类型。

访问请求服务的泛型类型以进行参数构造

YamlFileConfigurationSource不应该取决于你可以fileName使用typeof(TConfiguration)

public class YamlFileConfigurationSource<TConfiguration>
    : IConfigurationSource<TConfiguration> {
    public YamlFileConfigurationSource() { }
    public TConfiguration Current { 
        get {
            String fileName = typeof(TConfiguration).Name + ".config";
            // get config from fileName
        }
    }
}

如果要取消关联将TConfiguration转换为文件名的代码,则可以引入新组件。

public interface IConfigurationFileProvider<TConfiguration> {
    String GetFileName(); 
}
public class SimpleConfigurationFileProvider<TConfiguration>
    : IConfigurationFileProvider<TConfiguration>  {
    public String GetFileName() {
        return typeof(TConfiguration) + ".config";
    }
}

并将此依赖项添加到 YamlFileConfigurationSource 的构造函数上

注册将如下所示:

builder.RegisterGeneric(typeof(YamlFileConfigurationSource<>))
        .As(typeof(IConfigurationSource<>));
builder.RegisterGeneric(typeof(SimpleConfigurationFileProvider<>))
        .As(typeof(IConfigurationFileProvider<>));

顺便说一下,出于教育目的,这是使用WithParameter方法

的方法
builder.RegisterGeneric(typeof(YamlFileConfigurationSource<>))
        .As(typeof(IConfigurationSource<>))
        .WithParameter((pi, c) => pi.Name == "fileName",
                       (pi, c) => pi.Member.DeclaringType.GetGenericArguments()[0].Name);

它应该有效,但这是一种解决方法,而以前的解决方案更优雅。