<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Dependency Injection</title><link>https://community.telligent.com/community/11/w/developer-training/65129/dependency-injection</link><description /><dc:language>en-US</dc:language><generator>14.0.0.586 14</generator><item><title>Dependency Injection</title><link>https://community.telligent.com/community/11/w/developer-training/65129/dependency-injection</link><pubDate>Wed, 05 Aug 2020 14:22:44 GMT</pubDate><guid isPermaLink="false">5f17766b-bdfd-483f-b216-bb6237ee4005</guid><dc:creator>Former Member</dc:creator><comments>https://community.telligent.com/community/11/w/developer-training/65129/dependency-injection#comments</comments><description>Current Revision posted to Developer Training by Former Member on 08/05/2020 14:22:44&lt;br /&gt;
&lt;p&gt;If you use a &lt;a href="https://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency Injection&lt;/a&gt;&amp;nbsp;(DI)&amp;nbsp;framework in your code, or want to use one with your Verint Community customizations it is certainly possible. &amp;nbsp;There are a few things to take into consideration when implementing it however, specifically around when you create your service bindings in&amp;nbsp;your framework(sometimes also called a container or kernel depending on the framework) and when you can access or use the framework for injection. &amp;nbsp;Frameworks themselves are beyond the scope of this topic as there are many options. &amp;nbsp;You should research each type carefully to see if suits your needs and to see if it will work with your Verint Community.&lt;/p&gt;
&lt;p&gt;Verint Community itself uses its own dependency injection framework, however it is not something developers can bind services against or use to retrieve services for&amp;nbsp;themselves. &amp;nbsp;As a developer you are working with APIs and we provide a loader specifically for those. &amp;nbsp;Each API in the [[api-documentation:In-Process API Documentation|Developer Documentation]] shows how to load a core API using this service.&amp;nbsp;Additionally you can choose to register your own [[Custom APIs]].&lt;/p&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;h2&gt;&lt;a id="Binding_Your_Services" name="Binding_Your_Services"&gt;&lt;/a&gt;Binding Your Services&lt;/h2&gt;
&lt;p&gt;In most cases you initialize your DI framework when the application starts, however you do not have access to the application startup process within Verint Community. &amp;nbsp;Instead you can attempt to bind your services during plugin initialization which works for small customizations but can be unreliable if you wanted to use your container in other plugins during initialization since there is no guarantee on what order a plugins will initialize in. &amp;nbsp;Instead its best to use &amp;nbsp;a combination of a self initializing wrapper and the initialize event. &amp;nbsp;This will initialize your bindings on plugin initialization or the first time you access your wrapper.&lt;/p&gt;
&lt;h2&gt;&lt;a id="Service_Binding_Wrapper" name="Service_Binding_Wrapper"&gt;&lt;/a&gt;Service Binding Wrapper&lt;/h2&gt;
&lt;p&gt;This example creates a simple static class called &lt;code&gt;ServiceLocator&lt;/code&gt;. &amp;nbsp;Static is optional, if you wish to not have a static class or the framework you use would not work well with a static class, that is fine. &amp;nbsp;For the purposes of demonstration only it uses a fake DI framework&amp;nbsp;called &lt;code&gt;DependencyInjector&lt;/code&gt;. &amp;nbsp;You would substitute&amp;nbsp;your DI framework &amp;nbsp;binding code&amp;nbsp;as is required. &amp;nbsp; This class only exposes&amp;nbsp;a single method and that returns&amp;nbsp;the DI framework container(this may have different names depending on the framework but is essentially the container where you can retrieve your bindings from). &amp;nbsp;This way we can now interact with our DI framework directly. &amp;nbsp; What is important is the fact we wrap it in a property that always calls &lt;code&gt;EnsureInitialized()&lt;/code&gt;. &amp;nbsp;This method determines if all the services have been bound and if not it binds them. &amp;nbsp;It determines if initialization has run by checking to see if an equivalent container has been created.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;namespace Samples
{
    public static class ServiceLocator
    {
        private static DependencyInjectorContainer _injector = null;
        private static readonly object _lock = new object();

        public static DependencyInjectorContainer Service
        {
            get
            {
                EnsureInitialized(); //Make sure services are bound
                return _injector;
            }
        }

        public static void EnsureInitialized()
        {
            if (_injector != null)
                return; //Nothing to do

            lock (_lock)
            {
                if (_injector != null)
                    return; // Nothing to do
                    
                //Create your container for your DI framework
                var injector = new DependencyInjectorContainer();

                //Replace this with whatever your DI framework binding logic is.
                injector.AddBindingFor&amp;lt;ISampleService&amp;gt;(new SampleService());
                
                _injector = injector;
            }
        }
    }
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Whenever you access your DI framework from the property of the wrapper&amp;nbsp;class it will automatically ensure your services are bound correctly. &amp;nbsp;You can in turn force your services to bind if you choose by calling &lt;code&gt;ServiceLocator.EnsureInitialized().&lt;/code&gt; &amp;nbsp;This could be done in the &lt;code&gt;Initialize()&lt;/code&gt; method of a custom [[Plugins|plugin]].&lt;/p&gt;
&lt;h2&gt;&lt;a id="Loading_Your_Service" name="Loading_Your_Service"&gt;&lt;/a&gt;Loading Your Service&lt;/h2&gt;
&lt;p&gt;Getting a service from your DI framework will depend on how this is done in an individual framework. &amp;nbsp;Because we are simply exposing your DI framework container, once you have received a reference to it you interact with it like you would any other time. &amp;nbsp; The benefit however is that this will invoke the binding process if it is necessary.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;var service = ServiceLocator.Service.{Service Loading Method}(...);&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a id="Dependency_Injection_and_Plugins" name="Dependency_Injection_and_Plugins"&gt;&lt;/a&gt;Dependency Injection and Plugins&lt;/h2&gt;
&lt;p&gt;You can use DI with any custom service you write if its written in a way that works with whatever framework you&amp;nbsp;chose. &amp;nbsp; Plugins work differently and while you can still utilize DI to an extent there are some limitations.&lt;/p&gt;
&lt;p&gt;First you should not add a class implementing any&amp;nbsp;derivative&amp;nbsp;of &lt;code&gt;IPlugin&lt;/code&gt; to your DI framework bindings for 2 reasons. &amp;nbsp;First, plugins are loaded automatically and stored in memory by the Verint Community application. &amp;nbsp;They would not be read from your DI container meaning you would have potentially 2 instances out of sync. &amp;nbsp;Second you can retrieve plugins from memory using the [[api-documentation:PluginManager In-Process API Service|PluginManager]] and have no need to load them any other way. &amp;nbsp;If you have a service that is also a plugin, the best solution is separate them or leave it up to the plugin framework to manage.&lt;/p&gt;
&lt;p&gt;You can&amp;#39;t inject into plugins using traditional constructor injection. &amp;nbsp;Plugins themselves are&amp;nbsp;reflected by the platform and require a default(parameterless) constructor. &amp;nbsp;If you were to try to include a non parameterless constructor on a plugin it would result in an exception whenever the Verint Community&amp;nbsp;platform loads plugins. &amp;nbsp;You can however&amp;nbsp;create separate constructors where your parameterless constructor invokes the injectable constructor using the service locator wrapper class. &amp;nbsp;This allows the plugin to load but you can still maintain a way to inject services if needed.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt; public class SamplePlugin : IPlugin
    {
        private ISampleService _sampleService = null;
        public SamplePlugin(ISampleService sampleService)
        {
            _sampleService = sampleService;
        }

        //This calls our service locator
        public SamplePlugin():this(ServiceLocator.Service.GetBindingFor&amp;lt;ISampleService&amp;gt;())
        {
            
        }
        //... Plugin members left out for brevity
       
    }&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: best practices&lt;/div&gt;
</description></item><item><title>Dependency Injection</title><link>https://community.telligent.com/community/11/w/developer-training/65129/dependency-injection/revision/2</link><pubDate>Wed, 05 Aug 2020 14:22:30 GMT</pubDate><guid isPermaLink="false">5f17766b-bdfd-483f-b216-bb6237ee4005</guid><dc:creator>Former Member</dc:creator><comments>https://community.telligent.com/community/11/w/developer-training/65129/dependency-injection#comments</comments><description>Revision 2 posted to Developer Training by Former Member on 08/05/2020 14:22:30&lt;br /&gt;
&lt;p&gt;If you use a &lt;a href="https://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency Injection&lt;/a&gt;&amp;nbsp;(DI)&amp;nbsp;framework in your code, or want to use one with your Verint Community customizations it is certainly possible. &amp;nbsp;There are a few things to take into consideration when implementing it however, specifically around when you create your service bindings in&amp;nbsp;your framework(sometimes also called a container or kernel depending on the framework) and when you can access or use the framework for injection. &amp;nbsp;Frameworks themselves are beyond the scope of this topic as there are many options. &amp;nbsp;You should research each type carefully to see if suits your needs and to see if it will work with your Verint Community.&lt;/p&gt;
&lt;p&gt;Verint Community itself uses its own dependency injection framework, however it is not something developers can bind services against or use to retrieve services for&amp;nbsp;themselves. &amp;nbsp;As a developer you are working with APIs and we provide a loader specifically for those. &amp;nbsp;Each API in the [[api-documentation:In-Process API Documentation|Developer Documentation]] shows how to load a core API using this service.&amp;nbsp;Additionally you can choose to register your own [[Custom APIs]].&lt;/p&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;h2&gt;&lt;a id="Binding_Your_Services" name="Binding_Your_Services"&gt;&lt;/a&gt;Binding Your Services&lt;/h2&gt;
&lt;p&gt;In most cases you initialize your DI framework when the application starts, however you do not have access to the application startup process within Verint Community. &amp;nbsp;Instead you can attempt to bind your services during plugin initialization which works for small customizations but can be unreliable if you wanted to use your container in other plugins during initialization since there is no guarantee on what order a plugins will initialize in. &amp;nbsp;Instead its best to use &amp;nbsp;a combination of a self initializing wrapper and the initialize event. &amp;nbsp;This will initialize your bindings on plugin initialization or the first time you access your wrapper.&lt;/p&gt;
&lt;h2&gt;&lt;a id="Service_Binding_Wrapper" name="Service_Binding_Wrapper"&gt;&lt;/a&gt;Service Binding Wrapper&lt;/h2&gt;
&lt;p&gt;This example creates a simple static class called &lt;code&gt;ServiceLocator&lt;/code&gt;. &amp;nbsp;Static is optional, if you wish to not have a static class or the framework you use would not work well with a static class, that is fine. &amp;nbsp;For the purposes of demonstration only it uses a fake DI framework&amp;nbsp;called &lt;code&gt;DependencyInjector&lt;/code&gt;. &amp;nbsp;You would substitute&amp;nbsp;your DI framework &amp;nbsp;binding code&amp;nbsp;as is required. &amp;nbsp; This class only exposes&amp;nbsp;a single method and that returns&amp;nbsp;the DI framework container(this may have different names depending on the framework but is essentially the container where you can retrieve your bindings from). &amp;nbsp;This way we can now interact with our DI framework directly. &amp;nbsp; What is important is the fact we wrap it in a property that always calls &lt;code&gt;EnsureInitialized()&lt;/code&gt;. &amp;nbsp;This method determines if all the services have been bound and if not it binds them. &amp;nbsp;It determines if initialization has run by checking to see if an equivalent container has been created.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;namespace Samples
{
    public static class ServiceLocator
    {
        private static DependencyInjectorContainer _injector = null;
        private static readonly object _lock = new object();

        public static DependencyInjectorContainer Service
        {
            get
            {
                EnsureInitialized(); //Make sure services are bound
                return _injector;
            }
        }

        public static void EnsureInitialized()
        {
            if (_injector != null)
                return; //Nothing to do

            lock (_lock)
            {
                if (_injector != null)
                    return; // Nothing to do
                    
                //Create your container for your DI framework
                var injector = new DependencyInjectorContainer();

                //Replace this with whatever your DI framework binding logic is.
                injector.AddBindingFor&amp;lt;ISampleService&amp;gt;(new SampleService());
                
                _injector = injector;
            }
        }
    }
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Whenever you access your DI framework from the property of the wrapper&amp;nbsp;class it will automatically ensure your services are bound correctly. &amp;nbsp;You can in turn force your services to bind if you choose by calling &lt;code&gt;ServiceLocator.EnsureInitialized().&lt;/code&gt; &amp;nbsp;This could be done in the &lt;code&gt;Initialize()&lt;/code&gt; method of a custom [[Plugins|plugin]].&lt;/p&gt;
&lt;h2&gt;&lt;a id="Loading_Your_Service" name="Loading_Your_Service"&gt;&lt;/a&gt;Loading Your Service&lt;/h2&gt;
&lt;p&gt;Getting a service from your DI framework will depend on how this is done in an individual framework. &amp;nbsp;Because we are simply exposing your DI framework container, once you have received a reference to it you interact with it like you would any other time. &amp;nbsp; The benefit however is that this will invoke the binding process if it is necessary.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;var service = ServiceLocator.Service.{Service Loading Method}(...);&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a id="Dependency_Injection_and_Plugins" name="Dependency_Injection_and_Plugins"&gt;&lt;/a&gt;Dependency Injection and Plugins&lt;/h2&gt;
&lt;p&gt;You can use DI with any custom service you write if its written in a way that works with whatever framework you&amp;nbsp;chose. &amp;nbsp; Plugins work differently and while you can still utilize DI to an extent there are some limitations.&lt;/p&gt;
&lt;p&gt;First you should not add a class implementing any&amp;nbsp;derivative&amp;nbsp;of &lt;code&gt;IPlugin&lt;/code&gt; to your DI framework bindings for 2 reasons. &amp;nbsp;First, plugins are loaded automatically and stored in memory by the Verint Community application. &amp;nbsp;They would not be read from your DI container meaning you would have potentially 2 instances out of sync. &amp;nbsp;Second you can retrieve plugins from memory using the [[api-documentation:PluginManager In-Process API Service|PluginManager]] and have no need to load them any other way. &amp;nbsp;If you have a service that is also a plugin, the best solution is separate them or leave it up to the plugin framework to manage.&lt;/p&gt;
&lt;p&gt;You can&amp;#39;t inject into plugins using traditional constructor injection. &amp;nbsp;Plugins themselves are&amp;nbsp;reflected by the platform and require a default(parameterless) constructor. &amp;nbsp;If you were to try to include a non parameterless constructor on a plugin it would result in an exception whenever the Verint Community&amp;nbsp;platform loads plugins. &amp;nbsp;You can however&amp;nbsp;create separate constructors where your parameterless constructor invokes the injectable constructor using the service locator wrapper class. &amp;nbsp;This allows the plugin to load but you can still maintain a way to inject services if needed.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt; public class SamplePlugin : IPlugin
    {
        private ISampleService _sampleService = null;
        public SamplePlugin(ISampleService sampleService)
        {
            _sampleService = sampleService;
        }

        //This calls our service locator
        public SamplePlugin():this(ServiceLocator.Service.GetBindingFor&amp;lt;ISampleService&amp;gt;())
        {
            
        }
        //... Plugin members left out for brevity
       
    }&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item><item><title>Dependency Injection</title><link>https://community.telligent.com/community/11/w/developer-training/65129/dependency-injection/revision/1</link><pubDate>Thu, 13 Jun 2019 19:29:59 GMT</pubDate><guid isPermaLink="false">5f17766b-bdfd-483f-b216-bb6237ee4005</guid><dc:creator>Ben Tiedt</dc:creator><comments>https://community.telligent.com/community/11/w/developer-training/65129/dependency-injection#comments</comments><description>Revision 1 posted to Developer Training by Ben Tiedt on 06/13/2019 19:29:59&lt;br /&gt;
&lt;p&gt;If you use a &lt;a href="https://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency Injection&lt;/a&gt;(DI)&amp;nbsp;framework in your code, or want to use one with your Telligent Community customizations it is certainly possible. &amp;nbsp;There are a few things to take into consideration when implementing it however, specifically around when you create your service bindings in&amp;nbsp;your framework(sometimes also called a container or kernel depending on the framework) and when you can access or use the framework for injection. &amp;nbsp;Frameworks themselves are beyond the scope of this topic as there are many options. &amp;nbsp;You should research each type carefully to see if suits your needs and to see if it will work with your Telligent Community.&lt;/p&gt;
&lt;p&gt;Telligent Community itself uses its own dependency injection framework, however it is not something developers can bind services against or use to retrieve services for&amp;nbsp;themselves. &amp;nbsp;As a developer you are working with APIs and we provide a loader specifically for those. &amp;nbsp;Each API in the [[api-documentation:In-Process API Documentation|Developer Documentation]] shows how to load a core API using this service.&amp;nbsp;Additionally you can choose to register your own [[Custom APIs]].&lt;/p&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;h2&gt;&lt;a id="Binding_Your_Services" name="Binding_Your_Services"&gt;&lt;/a&gt;Binding Your Services&lt;/h2&gt;
&lt;p&gt;In most cases you initialize your DI framework when the application starts, however you do not have access to the application startup process within Telligent Community. &amp;nbsp;Instead you can attempt to bind your services during plugin initialization which works for small customizations but can be unreliable if you wanted to use your container in other plugins during initialization since there is no guarantee on what order a plugins will initialize in. &amp;nbsp;Instead its best to use &amp;nbsp;a combination of a self initializing wrapper and the initialize event. &amp;nbsp;This will initialize your bindings on plugin initialization or the first time you access your wrapper.&lt;/p&gt;
&lt;h2&gt;&lt;a id="Service_Binding_Wrapper" name="Service_Binding_Wrapper"&gt;&lt;/a&gt;Service Binding Wrapper&lt;/h2&gt;
&lt;p&gt;This example creates a simple static class called &lt;code&gt;ServiceLocator&lt;/code&gt;. &amp;nbsp;Static is optional, if you wish to not have a static class or the framework you use would not work well with a static class, that is fine. &amp;nbsp;For the purposes of demonstration only it uses a fake DI framework&amp;nbsp;called &lt;code&gt;DependencyInjector&lt;/code&gt;. &amp;nbsp;You would substitute&amp;nbsp;your DI framework &amp;nbsp;binding code&amp;nbsp;as is required. &amp;nbsp; This class only exposes&amp;nbsp;a single method and that returns&amp;nbsp;the DI framework container(this may have different names depending on the framework but is essentially the container where you can retrieve your bindings from). &amp;nbsp;This way we can now interact with our DI framework directly. &amp;nbsp; What is important is the fact we wrap it in a property that always calls &lt;code&gt;EnsureInitialized()&lt;/code&gt;. &amp;nbsp;This method determines if all the services have been bound and if not it binds them. &amp;nbsp;It determines if initialization has run by checking to see if an equivalent container has been created.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;namespace Samples
{
    public static class ServiceLocator
    {
        private static DependencyInjectorContainer _injector = null;
        private static readonly object _lock = new object();

        public static DependencyInjectorContainer Service
        {
            get
            {
                EnsureInitialized(); //Make sure services are bound
                return _injector;
            }
        }

        public static void EnsureInitialized()
        {
            if (_injector != null)
                return; //Nothing to do

            lock (_lock)
            {
                if (_injector != null)
                    return; // Nothing to do
                    
                //Create your container for your DI framework
                var injector = new DependencyInjectorContainer();

                //Replace this with whatever your DI framework binding logic is.
                injector.AddBindingFor&amp;lt;ISampleService&amp;gt;(new SampleService());
                
                _injector = injector;
            }
        }
    }
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Whenever you access your DI framework from the property of the wrapper&amp;nbsp;class it will automatically ensure your services are bound correctly. &amp;nbsp;You can in turn force your services to bind if you choose by calling &lt;code&gt;ServiceLocator.EnsureInitialized().&lt;/code&gt; &amp;nbsp;This could be done in the &lt;code&gt;Initialize()&lt;/code&gt; method of a custom [[Plugins|plugin]].&lt;/p&gt;
&lt;h2&gt;&lt;a id="Loading_Your_Service" name="Loading_Your_Service"&gt;&lt;/a&gt;Loading Your Service&lt;/h2&gt;
&lt;p&gt;Getting a service from your DI framework will depend on how this is done in an individual framework. &amp;nbsp;Because we are simply exposing your DI framework container, once you have received a reference to it you interact with it like you would any other time. &amp;nbsp; The benefit however is that this will invoke the binding process if it is necessary.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt;var service = ServiceLocator.Service.{Service Loading Method}(...);&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a id="Dependency_Injection_and_Plugins" name="Dependency_Injection_and_Plugins"&gt;&lt;/a&gt;Dependency Injection and Plugins&lt;/h2&gt;
&lt;p&gt;You can use DI with any custom service you write if its written in a way that works with whatever framework you&amp;nbsp;chose. &amp;nbsp; Plugins work differently and while you can still utilize DI to an extent there are some limitations.&lt;/p&gt;
&lt;p&gt;First you should not add a class implementing any&amp;nbsp;derivative&amp;nbsp;of &lt;code&gt;IPlugin&lt;/code&gt; to your DI framework bindings for 2 reasons. &amp;nbsp;First, plugins are loaded automatically and stored in memory by the Telligent Community application. &amp;nbsp;They would not be read from your DI container meaning you would have potentially 2 instances out of sync. &amp;nbsp;Second you can retrieve plugins from memory using the [[api-documentation:PluginManager In-Process API Service|PluginManager]] and have no need to load them any other way. &amp;nbsp;If you have a service that is also a plugin, the best solution is separate them or leave it up to the plugin framework to manage.&lt;/p&gt;
&lt;p&gt;You can&amp;#39;t inject into plugins using traditional constructor injection. &amp;nbsp;Plugins themselves are&amp;nbsp;reflected by the platform and require a default(parameterless) constructor. &amp;nbsp;If you were to try to include a non parameterless constructor on a plugin it would result in an exception whenever the Telligent Community&amp;nbsp;platform loads plugins. &amp;nbsp;You can however&amp;nbsp;create separate constructors where your parameterless constructor invokes the injectable constructor using the service locator wrapper class. &amp;nbsp;This allows the plugin to load but you can still maintain a way to inject services if needed.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="csharp"&gt; public class SamplePlugin : IPlugin
    {
        private ISampleService _sampleService = null;
        public SamplePlugin(ISampleService sampleService)
        {
            _sampleService = sampleService;
        }

        //This calls our service locator
        public SamplePlugin():this(ServiceLocator.Service.GetBindingFor&amp;lt;ISampleService&amp;gt;())
        {
            
        }
        //... Plugin members left out for brevity
       
    }&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item></channel></rss>