为参数构造访问请求服务的通用类型

Access generic type of requested service for parameter construction

我有一个强类型配置的服务合同:

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);

它应该可以工作,但它是一种解决方法,而以前的解决方案更优雅。