一千萬個為什麽

搜索

感謝@dtb的幫助,他建議真的需要一段通用服務定位器的代碼

static class Locator
{
    private static class LocatorEntry where T : ...
    {
        public static IDataManager instance;
    }

    public static void Register(IDataManager instance) where T : ...
    {
        LocatorEntry.instance = instance;
    }

    public static IDataManager GetInstance() where T : ...
    {
        return LocatorEntry.instance;
    }
}

但是在我以前的版本中,我使用了裝配上的反射來發現數百個DataManager

我想寫一個方法發現如下

void Discover()
        {
            var pManager = new ProtocolSQLDataManager();
            Register(pManager);

            var rManager = new ResultSQLDataManager();
            Register(rManager);

            var gType = typeof(ISQLDataAccessManager<>);

            foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
            {               
                if (type.IsSubclassOf(gType) && !type.IsAbstract))
                {
                    var manager = Activator.CreateInstance(type);
                   //put something here in order to make next line of code works
                    Register(manager);
                }
            }
        }

如何將 type 強制轉換為適當的類型以使Register工作(並調用適當的Register?

更新:我明白了

            foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
            {
                if ( type.GetInterface("IDataAccessManager`1") != null && !type.IsAbstract)
                {
                    var manager = Activator.CreateInstance(type);
                    var t = type.GetInterface("IDataAccessManager`1").GetGenericArguments()[0];
                    typeof(GenLocator)
                        .GetMethod("Register")
                        .MakeGenericMethod(t)
                        .Invoke(null, new[] { manager });
                }
            }

最佳答案

您需要使用反射調用 Register ,如下所示:

typeof(Locator)
    .GetMethod("Register")
    .MakeGenericMethod(type)
    .Invoke(null, manager);

轉載註明原文: 發現泛型類型

猜你喜歡