根据字符串参数注入类型
Inject Type based on string parameter
我想让 IoC 根据参数创建类型。我还需要有关在何处存储此参数信息的指导。
我需要根据字符串文件类型制作 classes,更具体地说,基于扩展名。
我有一个简单的数据文件信息 class:
class info
{
public string FileName { get; set; }
}
我需要 return classes 基于那个“FileName
”扩展,这样我就可以呈现查看器。
我在 WPF 中使用 DataTemplates 并将类型分配给视图效果很好。我只需要根据 FileName
.
分配类型
现在我只是使用静态扩展字符串数组 new[]{".pdf",".html",".jpg"};
来确定要 return 的类型。这是完全不可持续的。
我想要一个如下所示的数据源:
Extension Type
============= =============
.pdf Webviewer
.html Webviewer
.doc Docviewer
.docx Docviewer
.txt Textviewer
等等
取决于您使用的 DI 容器。例如,Simple Injector 提供了基于键解决依赖关系的方法:https://simpleinjector.readthedocs.org/en/latest/howto.html#resolve-instances-by-key
这是 case 语句、数据库 table、工厂模式和 IoC 之间的灰色地带。正确的解决方案完全基于您处理的不同文件的数量。这是一个小框架,可以 "act like" 一个 Ioc 容器供您使用,并允许您在应用程序中的单个位置定义扩展 => 查看器映射。
为您的观众提供一个公共界面或基础 class:
public interface IViewer {
void LaunchViewer(string fileName);
}
制作映射 class:
public class FileExtensionMap {
private Dictionary<string, IViewer> maps;
public IViewer this[string key] {
get {
if (!this.maps.ContainsKey(key)) {
throw new KeyNotFoundException();
}
return this.maps[key];
}
}
public FileExtensionMap() {
this.maps = new Dictionary<string, IViewer>();
this.LoadMaps();
}
public void LoadMaps() {
this.maps.Add("PDF", new PdfViewer());
this.maps.Add("DOC", new WordViewer());
}
}
将您的 FileExtensionMap 实例定义为单例或静态 class,随您喜欢。
一个简短的例子。你要么引用你的静态,你的单例,要么将映射器作为依赖项传递给你的调用 class:
public class Example {
FileExtensionMap map;
public Example(FileExtensionMap map) {
this.map = map;
}
public void View(FileInfo file) {
map[file.Extension].LaunchViewer(file.Name);
}
}
更新的映射 class 将为每次调用实例化一个新实例:
public class FileExtensionMap {
private Dictionary<string, Func<IViewer>> maps;
public IViewer this[string key] {
get {
if (!this.maps.ContainsKey(key)) {
throw new KeyNotFoundException();
}
return this.maps[key].Invoke();
}
}
public FileExtensionMap() {
this.maps = new Dictionary<string, Func<IViewer>>();
this.LoadMaps();
}
public void LoadMaps() {
this.maps.Add("PDF", () => new PdfViewer());
this.maps.Add("DOC", () => new WordViewer());
}
}
Unity IoC 允许使用名称注册类型。该名称可以是文件扩展名。我假设所有查看器都实现了 IViewer
接口。
// Register the viewer types
var viewers = new UnityContainer();
viewers
.RegisterType<IViewer, Webwiewer>(".jpeg")
.RegisterType<IViewer, Docviewer>(".doc");
// Get a viewer
var viewer = viewers.Resolve<IViewer>(ext);
我想让 IoC 根据参数创建类型。我还需要有关在何处存储此参数信息的指导。
我需要根据字符串文件类型制作 classes,更具体地说,基于扩展名。
我有一个简单的数据文件信息 class:
class info
{
public string FileName { get; set; }
}
我需要 return classes 基于那个“FileName
”扩展,这样我就可以呈现查看器。
我在 WPF 中使用 DataTemplates 并将类型分配给视图效果很好。我只需要根据 FileName
.
现在我只是使用静态扩展字符串数组 new[]{".pdf",".html",".jpg"};
来确定要 return 的类型。这是完全不可持续的。
我想要一个如下所示的数据源:
Extension Type
============= =============
.pdf Webviewer
.html Webviewer
.doc Docviewer
.docx Docviewer
.txt Textviewer
等等
取决于您使用的 DI 容器。例如,Simple Injector 提供了基于键解决依赖关系的方法:https://simpleinjector.readthedocs.org/en/latest/howto.html#resolve-instances-by-key
这是 case 语句、数据库 table、工厂模式和 IoC 之间的灰色地带。正确的解决方案完全基于您处理的不同文件的数量。这是一个小框架,可以 "act like" 一个 Ioc 容器供您使用,并允许您在应用程序中的单个位置定义扩展 => 查看器映射。
为您的观众提供一个公共界面或基础 class:
public interface IViewer {
void LaunchViewer(string fileName);
}
制作映射 class:
public class FileExtensionMap {
private Dictionary<string, IViewer> maps;
public IViewer this[string key] {
get {
if (!this.maps.ContainsKey(key)) {
throw new KeyNotFoundException();
}
return this.maps[key];
}
}
public FileExtensionMap() {
this.maps = new Dictionary<string, IViewer>();
this.LoadMaps();
}
public void LoadMaps() {
this.maps.Add("PDF", new PdfViewer());
this.maps.Add("DOC", new WordViewer());
}
}
将您的 FileExtensionMap 实例定义为单例或静态 class,随您喜欢。
一个简短的例子。你要么引用你的静态,你的单例,要么将映射器作为依赖项传递给你的调用 class:
public class Example {
FileExtensionMap map;
public Example(FileExtensionMap map) {
this.map = map;
}
public void View(FileInfo file) {
map[file.Extension].LaunchViewer(file.Name);
}
}
更新的映射 class 将为每次调用实例化一个新实例:
public class FileExtensionMap {
private Dictionary<string, Func<IViewer>> maps;
public IViewer this[string key] {
get {
if (!this.maps.ContainsKey(key)) {
throw new KeyNotFoundException();
}
return this.maps[key].Invoke();
}
}
public FileExtensionMap() {
this.maps = new Dictionary<string, Func<IViewer>>();
this.LoadMaps();
}
public void LoadMaps() {
this.maps.Add("PDF", () => new PdfViewer());
this.maps.Add("DOC", () => new WordViewer());
}
}
Unity IoC 允许使用名称注册类型。该名称可以是文件扩展名。我假设所有查看器都实现了 IViewer
接口。
// Register the viewer types
var viewers = new UnityContainer();
viewers
.RegisterType<IViewer, Webwiewer>(".jpeg")
.RegisterType<IViewer, Docviewer>(".doc");
// Get a viewer
var viewer = viewers.Resolve<IViewer>(ext);