Feedback

C# - IServiceProvider: Try GetService()

Veröffentlicht von am 27.03.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.
GFU-Schulungen  [Anzeige]

Visual Studio Team Foundation Server 2017/2015 (TFS) - Komplett 

ASP.NET Core und Angular Komplett für .NET-Entwickler

Sie  lernen in drei (3) Tagen wie man mit  ASP.NET Core und den Technologien  MVC, Entity Framework, WebAPI und  Razor professionelle sowie moderne  Web-Anwendungsarchitekturen aufbaut.  Die Schulung ist der perfekte  Einstieg um insbesondere datengetriebene  und präsentationsorientierte  Applikationen auf Basis der robusten und  skalierbaren ASP.NET Core  Plattform zu erstellen. Nach der Veranstaltung kennen Sie die Konzepte von Angular und können Angular in neue und bestehende ASP.NET-Anwendungen einsetzen.

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!