Откройте для себя универсальные типы - PullRequest
0 голосов
/ 17 апреля 2010

Спасибо @dtb за помощь, он посоветовал действительно нужен кусок кода для универсального локатора службы

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

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

    public static IDataManager<T> GetInstance<T>() where T : ...
    {
        return LocatorEntry<T>.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<T>(manager);
                }
            }
        }

Как привести type к соответствующему типу, чтобы заставить Регистр работать (и вызвать соответствующий Регистр?

ОБНОВЛЕНИЕ: Iпонял это

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

1 Ответ

3 голосов
/ 17 апреля 2010

Вам нужно позвонить Register, используя отражение, например:

typeof(Locator)
    .GetMethod("Register")
    .MakeGenericMethod(type)
    .Invoke(null, manager);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...