Feedback

C# - IServiceProvider: Try GetService()

Veröffentlicht von am 3/27/2013
(1 Bewertungen)
In .Net ist das Interface System.IServiceProvider eine einfache und elegante Möglichkeit, Dienste von anderen Objekten abzufragen, ohne genau wissen zu müssen - oder gar zu wollen -, wie die Klassenstruktur dahinter aufgebaut ist. Ist das Interface in dieser Klasse implementiert oder in einer anderen? Egal, man fragt IServiceProvider und bekommt eine Instanz dessen, was man angefragt hat.

Soweit die Theorie. In der Praxis vergisst man als Entwickler dann aber vielleicht doch mal, ein weiteres Interface in die Liste aufzunehmen, sobald man es implementiert hat. Oder IServiceProvider wurde ganz und gar vergessen.

Deshalb hier meine Methode, mit Fallback-Strategie dennoch zum gewünschten Ergebnis zu kommen.

-----

In .Net the Interface System.IServiceProvider is a simple and elegant method to query services from other objects without having - or even wanting - to know how the class structure behind it looks like. Is the interface at that class implemented or at another? No matter, you query IServiceProvider and you get an instance of what you asked for.

That's the theory. In reality the developer may have forgotten to add the new interface to the list after he implemented it. Or he forgot the IServiceProvider altogether.

That's why I have this method to get what I want through several fallback strategies.
using System;
using System.Diagnostics;

public static class Program
{
    private static T TryGetService<T>(Object potentialServiceProvider) 
        where T : class
    {
        T service;
        IServiceProvider serviceProvider;

        if (potentialServiceProvider == null)
        {
            return (null);
        }
        service = null;
        serviceProvider = potentialServiceProvider as IServiceProvider;
        if (serviceProvider != null)
        {
            service = serviceProvider.GetService(typeof(T)) as T;
        }
        if (service == null)
        {
            service = potentialServiceProvider as T;
        }
        return (service);
    }

    public static void Main()
    {
        ClassAB classAB;
        ClassC classC;
        InterfaceA interfaceA;
        InterfaceB interfaceB;
        InterfaceC interfaceC;
        InterfaceD interfaceD;

        classAB = new ClassAB();
        interfaceA = TryGetService<InterfaceA>(classAB);
        Debug.Assert(interfaceA != null);
        interfaceB = TryGetService<InterfaceB>(classAB);
        Debug.Assert(interfaceB != null);
        interfaceC = TryGetService<InterfaceC>(classAB);
        Debug.Assert(interfaceC != null);
        interfaceD = TryGetService<InterfaceD>(classAB);
        Debug.Assert(interfaceD == null);
        classC = new ClassC();
        interfaceC = TryGetService<InterfaceC>(classC);
        Debug.Assert(interfaceC != null);
        interfaceD = TryGetService<InterfaceD>(classC);
        Debug.Assert(interfaceD == null);
    }
}

interface InterfaceA { }

interface InterfaceB { }

interface InterfaceC { }

interface InterfaceD { }

internal class ClassAB : InterfaceA, InterfaceB, IServiceProvider
{
    private ClassC m_ClassC = new ClassC();

    public Object GetService(Type serviceType)
    {
        if (serviceType == typeof(InterfaceA))
        {
            return (this);
        }
        else if (serviceType == typeof(InterfaceC))
        {
            return (this.m_ClassC);
        }
        //We forgot to register InterfaceB here
        return (null);
    }
}

internal class ClassC : InterfaceC { }

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!