Question

I have say a dozen types T which inherit from EntityObject and IDataObject. I have generic the following interface

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

I have also base class for data managers

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

And i have particular classes

public class Result : EntityObject, IDataObject ....

public class ResultDataManager : BaseDataManager<Result> ...

I want to implement service locator, which will return instance of IDataManager<T> for T

But I stucked how to implement it in a neat way without a lot of castings.

Any ideas?

UPDATE: I used to use the following code for discovering types for registring them with my previous service locator:

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

It seems that I don't really understand reflection with generics

Was it helpful?

Solution

Here is a neat solution if having the locator as singleton is fine:

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

If you cannot implement the locator as singleton, I believe there is no there around creating a Dictionary<Type,object> and do some casts:

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)];
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top