{"id":1187,"date":"2013-03-27T08:19:46","date_gmt":"2013-03-27T07:19:46","guid":{"rendered":"http:\/\/doena-journal.net\/en\/?p=1187"},"modified":"2021-09-27T15:44:14","modified_gmt":"2021-09-27T13:44:14","slug":"my-getservice-pattern","status":"publish","type":"post","link":"https:\/\/doena-journal.net\/en\/1187\/my-getservice-pattern","title":{"rendered":"My GetService Pattern"},"content":{"rendered":"<p>In .Net the Interface <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.iserviceprovider.aspx\">System.IServiceProvider<\/a> is a simple and elegant method to query services from other objects without having &#8211; or even wanting &#8211; 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.<\/p>\n<p>That&#8217;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.<\/p>\n<p>That&#8217;s why I have this method to get what I want through several fallback strategies:<\/p>\n<p><!--more--><\/p>\n<pre>\r\nusing System;\r\nusing System.Diagnostics;\r\n\r\npublic static class Program\r\n{\r\n  private static T TryGetService&lt;T&gt;(Object potentialServiceProvider) \r\n    where T : class\r\n  {\r\n    T service;\r\n    IServiceProvider serviceProvider;\r\n\r\n    if (potentialServiceProvider == null)\r\n    {\r\n      return (null);\r\n    }\r\n    service = null;\r\n    serviceProvider = potentialServiceProvider as IServiceProvider;\r\n    if (serviceProvider != null)\r\n    {\r\n      service = serviceProvider.GetService(typeof(T)) as T;\r\n    }\r\n    if (service == null)\r\n    {\r\n      service = potentialServiceProvider as T;\r\n    }\r\n    return (service);\r\n  }\r\n\r\n  public static void Main()\r\n  {\r\n    ClassAB classAB;\r\n    ClassC classC;\r\n    InterfaceA interfaceA;\r\n    InterfaceB interfaceB;\r\n    InterfaceC interfaceC;\r\n    InterfaceD interfaceD;\r\n\r\n    classAB = new ClassAB();\r\n    interfaceA = TryGetService&lt;InterfaceA&gt;(classAB);\r\n    Debug.Assert(interfaceA != null);\r\n    interfaceB = TryGetService&lt;InterfaceB&gt;(classAB);\r\n    Debug.Assert(interfaceB != null);\r\n    interfaceC = TryGetService&lt;InterfaceC&gt;(classAB);\r\n    Debug.Assert(interfaceC != null);\r\n    interfaceD = TryGetService&lt;InterfaceD&gt;(classAB);\r\n    Debug.Assert(interfaceD == null);\r\n    classC = new ClassC();\r\n    interfaceC = TryGetService&lt;InterfaceC&gt;(classC);\r\n    Debug.Assert(interfaceC != null);\r\n    interfaceD = TryGetService&lt;InterfaceD&gt;(classC);\r\n    Debug.Assert(interfaceD == null);\r\n  }\r\n}\r\n\r\ninterface InterfaceA { }\r\n\r\ninterface InterfaceB { }\r\n\r\ninterface InterfaceC { }\r\n\r\ninterface InterfaceD { }\r\n\r\ninternal class ClassAB : InterfaceA, InterfaceB, IServiceProvider\r\n{\r\n  private ClassC m_ClassC = new ClassC();\r\n\r\n  public Object GetService(Type serviceType)\r\n  {\r\n    if (serviceType == typeof(InterfaceA))\r\n    {\r\n      return (this);\r\n    }\r\n    else if (serviceType == typeof(InterfaceC))\r\n    {\r\n      return (this.m_ClassC);\r\n    }\r\n    \/\/We forgot to register InterfaceB here\r\n    return (null);\r\n  }\r\n}\r\n\r\ninternal class ClassC : InterfaceC { }\r\n<\/pre>\n<p>If it still doesn&#8217;t work, then you&#8217;ve at least tried. \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In .Net the Interface System.IServiceProvider is a simple and elegant method to query services from other objects without having &#8211; or even wanting &#8211; to&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,870],"tags":[1454,1453,1473],"class_list":["post-1187","post","type-post","status-publish","format-standard","hentry","category-misc","category-software","tag-net","tag-c","tag-iserviceprovider"],"_links":{"self":[{"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/posts\/1187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/comments?post=1187"}],"version-history":[{"count":13,"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/posts\/1187\/revisions"}],"predecessor-version":[{"id":1556,"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/posts\/1187\/revisions\/1556"}],"wp:attachment":[{"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/media?parent=1187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/categories?post=1187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/doena-journal.net\/en\/wp-json\/wp\/v2\/tags?post=1187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}