1

In my application I have the following class to get instances of an interface:

public static class ServiceProvider
{
    private static readonly Dictionary<Type, dynamic> _serviceStorage;
    private static readonly object _serviceLock;

    static ServiceProvider()
    {
        _serviceLock = new object();
        _serviceStorage = new Dictionary<Type, dynamic>();
    }

    public static T GetService<T>()
    {
        Type serviceType = typeof (T);
        lock (_serviceLock)
        {
            if (!_serviceStorage.ContainsKey(serviceType))
            {
                _serviceStorage.Add(serviceType, (T) CreateService(serviceType));
            }
        }
        return _serviceStorage[serviceType];
    }

    private static dynamic CreateService(Type serviceType)
    {
        Type implementationType = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(assembly => assembly.GetTypes())
            .FirstOrDefault(type => serviceType.IsAssignableFrom(type) && type.IsClass);
        if (implementationType == null)
            throw new NullReferenceException();
        return Activator.CreateInstance(implementationType);
    }
}

The implementation-class must implement the provided interface and have a parameterless constructor.

For example I have the interface IEventRegistrationService which looks something like:

public interface IEventRegistrationService
{
  void Register(string name, Action<object> callback);
}

and the implementation-class looks like:

internal class EventRegistrationService : IEventRegistrationService
{
  public void Register(string name, Action<object> callback)
  {
     // Register the action with this name...
  }
}

And the usage of my service looks like:

IEventRegistrationService service = ServiceProvider.GetService<IEventRegistrationService>();

Now I have an instance of my interface. Everything just works fine until here.

Now I want to make the IEventRegistrationService-interface generic to have the correct type in the callback-action. The "new" interface should look like:

public interface IEventRegistrationService<T>
{
  void Register(string name, Action<T> callback);
}

And the implementation-class now looks like:

internal class EventRegistrationService<T> : IEventRegistrationService<T>
{
   public void Register(string name, Action<T> callback)
   {
      // Register the action with this name...
   }
}

And the usage should be like:

IEventRegistrationService<string> service = ServiceProvider.GetService<IEventRegistrationService<string>>();

But with this generic I get an exception in ServiceProvider-class in the CreateService method.

The statement:

 Type implementationType = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(assembly => assembly.GetTypes())
                .FirstOrDefault(type => serviceType.IsAssignableFrom(type) && type.IsClass);

returns null.

I guess this is because of the .IsAssignableFrom(type) but I don't know how to solve this problem.

How can I check if a class implements a generic interface?

Edit:

I don't know what interface-type is expected.

Tomtom
  • 9,087
  • 7
  • 52
  • 95

0 Answers0