为参数构造访问请求服务的通用类型
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);
它应该可以工作,但它是一种解决方法,而以前的解决方案更优雅。
我有一个强类型配置的服务合同:
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);
它应该可以工作,但它是一种解决方法,而以前的解决方案更优雅。