Сервисный локатор для дженериков - PullRequest
1 голос
/ 17 апреля 2010

Я скажу дюжину типов T, которые наследуются от EntityObject и IDataObject. У меня есть универсальный следующий интерфейс

IDataManager<T> where T : EntityObject, IDataObject ...

У меня также есть базовый класс для менеджеров данных

BaseDataManager<T> : IDataManager<T> where T : EntityObject, IDataObject ....

И у меня есть определенные классы

public class Result : EntityObject, IDataObject ....

public class ResultDataManager : BaseDataManager<Result> ...

Я хочу реализовать сервисный локатор, который будет возвращать экземпляр IDataManager<T> для T

Но я застрял, как реализовать это аккуратно, без большого количества отливок.

Есть идеи?

UPDATE: Раньше я использовал следующий код для обнаружения типов для регистрации их в моем предыдущем сервисном локаторе:

 foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (type.GetInterface("ISQLDataAccessManager") != null && !type.IsAbstract)
                {
                    var manager = (ISQLDataAccessManager)Activator.CreateInstance(type);

                    _managers.Add(type, manager);

                    var typeDO = manager.GetDataObjectType();

                    _typeNames2Types.Add(typeDO.FullName, typeDO);
                    _managers2BO.Add(typeDO, manager);
                }
            }

Кажется, я не совсем понимаю отражение с помощью дженериков

1 Ответ

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

Вот точное решение, если с локатором в качестве синглтона все в порядке:

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

Если вы не можете реализовать локатор как синглтон, я думаю, что нет ничего вокруг создания словаря и сделайте несколько приведений:

class Locator
{
    private readonly Dictionary<Type, object> instances;

    public Locator
    {
        this.instances = new Dictionary<Type, object>();
    }

    public void Register<T>(IDataManager<T> instance) where T : ...
    {
        this.instances[typeof(T)] = instance;
    }

    public IDataManager<T> GetInstance<T>() where T : ...
    {
        return (IDataManager<T>)this.instances[typeof(T)];
    }
}
...