【问题标题】:Programatically fetching Singleton instances that implement a common interface以编程方式获取实现公共接口的 Singleton 实例
【发布时间】:2016-01-29 13:57:22
【问题描述】:

我正在使用一些遗留的 ASP.NET MVC 代码,其中包含许多相当详细的 XML 配置文件。每个文件在运行时被加载到定义为 Singleton 类的对象表示中。

我不想通过类类型专门引用每个单例,我想要一种以编程方式获取它们中的每一个,然后能够基于它们都必须实现的接口访问它们共同的属性和方法的方法。

例如,这些单例都有一个名为“Filename”的字符串实例属性,即它们所代表的配置文件的名称。因此,我想自动生成这些文件名的列表,而无需手动引用每个单例来获取属性,因此我需要以编程方式获取所有实现指定 Filename 属性的接口的单例实例,然后通过以下方式获取该属性值投射到那个界面。

这可能吗?

【问题讨论】:

  • 你能提供你的单例类的布局吗?
  • 它们很重,会占用太多空间来完整发布,但本质上它们只是典型的单例实现,每个都有自己的特定类类型,而不是从任何东西继承,而是实现一个通用接口,只公开少数公共实例属性和方法。

标签: c# .net reflection singleton


【解决方案1】:

你提到了一个简单的单例布局,所以我用它来测试:

public interface IConfig { }

public class Config1 : IConfig
{
    public static Config1 Config = new Config1();

    private Config1()
    {
        FileName = "file.xml";
    }

    public string FileName { get; private set; }
}

要获取所有文件名,您可以使用这组 linq:

var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(a => a.GetTypes())
    .Where(x => typeof (IConfig).IsAssignableFrom(x) && !x.IsAbstract)
    .ToList();

var objects = types.Select(x => x.GetFields().Single(y => x == y.FieldType).GetValue(null))
    .ToList();

var fileNames = objects.Select(x => x.GetType().GetProperty("FileName").GetValue(x)).ToList();

也许您必须更改程序集才能根据需要进行搜索。

【讨论】:

  • 干杯,我最终意识到我已经尝试过类似的东西,但它没有奏效的原因是因为我在某个配置实例化期间调用的某个地方执行此操作,因此创建了堆栈溢出导致我之前错误地认为类似的方法有问题!
猜你喜欢
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 2011-02-22
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
相关资源
最近更新 更多