Dependency Injection on SignalR - Blogs
X
05Nov

Dependency Injection on SignalR

                                                       Dependency Injection on SignalR

This article shows how to perform dependency injection on SignalR hubs.

Dependency injection is a way to remove hard-coded dependencies between objects, making it easier to replace an object's dependencies, either for testing (using mock objects) or to change run-time behaviour.

What is Dependency Injection?                                                                                                 

If you are already familiar with DI skip this section.

Dependency injection (DI) is a pattern where objects are not responsible for creating their own dependencies.

Here I given some examples to motivate DI. Suppose you have object that need to create Error log management. There two types of log management given below

  • Text file viewer
  • Event viewer

Now I’m going to create interface class first as a ILog that has one method to write the error log after that this method inherited by other log classes.

namespace DependencyInjection

{

    public interface Ilog

    {

        void Messagelog(Exception ex);

    }

}

Text file Viewer Class

Now create a class, Filelogger class that inherits the ILog interface. This class writes an error log into text file.

using System;

using System.Configuration;

using System.IO;

namespace DependencyInjection

{

    public class Filelogger:Ilog

    {

        public void Messagelog(Exception ex)

        {

            string folderPath = @"D:/logs/";

            if (!(Directory.Exists(folderPath)))

            {

                Directory.CreateDirectory(folderPath);

            }

            FileStream objFileStrome = new FileStream(folderPath + "errlog.txt", FileMode.Append, FileAccess.Write);

            StreamWriter objStreamWriter = new StreamWriter(objFileStrome);

            objStreamWriter.Write("Message: " + ex.Message + Environment.NewLine);

            objStreamWriter.Write("StackTrace: " + ex.StackTrace + Environment.NewLine);

            objStreamWriter.Write("Date/Time: " + DateTime.Now.ToString() + Environment.NewLine);

            objStreamWriter.Write("============================================");

            objStreamWriter.Close();

            objFileStrome.Close(); 

           }

    }

}

Event Viewer Class

Now create one more class EventViewerLogger class that inherits ILog interface. This class write an error log message in the event viewer.

using System;

using System.Configuration;

using System.Diagnostics;

namespace DependencyInjection

{

    public class EventViewerLogger:Ilog

    {

        public void Messagelog(Exception ex) 

        { 

            EventLog objEventLog = new EventLog();

            string sourceName = "DependencyInjection";

            if (!(EventLog.SourceExists(sourceName)))

            {

                EventLog.CreateEventSource(sourceName, "ErrorLog");

            } 

            objEventLog.Source = sourceName; 

            string message = String.Format("Message: {0} \n StackTrace: {1} \n Date/Time: {2} ", ex.Message, ex.StackTrace,                                   DateTime.Now.ToString()); 

            objEventLog.WriteEntry(message, EventLogEntryType.Error); 

        } 

    } 

}

Operation Class:

Before understanding the concept of Dependency Injection (DI) you need to understand the two concepts of object oriented programming mentioned below

  1. Tightly coupling – Tightly coupling is when a group of class are highly depends on one another.
  2. Loosely coupling –Loosely coupling is achieved by means of design that promotes single-responsibility and separation of concern.

Now create a one more class to understand the concept of tightly coupling. The Operation class has Interface class ILog instance which has been create by  Filelogger Class.

Here Operation class objects are tightly coupled with Filelogger class.

using System;

namespace DependencyInjection

{

    public class Operation

    {

        Ilog logger = new Filelogger();

        public void Division()

        {

            try

            {

                int AvgGain = 10000, AvgLoss = 0, rs;

                rs = AvgGain / AvgLoss;

                Console.WriteLine("Result is :{0}", rs);

            }

            catch (DivideByZeroException ex)

            {

                logger.Messagelog(ex);

            }

        }

    }

}

The above code works perfectly but not the best design to do that because it is tightly coupled with Filelogger.supposing that a lot of other objects use Filelogger,you will need to change all of them.so you need to change throughout the application.

So this is not depending on the Open closed principle of object oriented programming.

Main Program (without dependency injection):

Now call your class method in your application start up class you get in the text file so you start up the class like below

using System;

namespace DependencyInjection

{

       class Program

    {

        

        static void Main(string[] args)

           {

               Operation objOperation = new Operation();

               objOperation.Division();

               Console.Read();

              

        }

    }

}

Let run the application you will get an exception in the log file show below figure.

filelog

A better approach is to inject ILog into object by using constructor dependency injection.

With Constructor Dependency Injection

The Constructor Injection uses a parameter to inject dependencies so there is normally one parameterized constructor always. So in this constructor dependency, the object has no default constructor and you need to pass specified values at the time of creation to initiate the object.

Now your design is loosely coupled with use of constructor Dependency.

Let’s create OperationEvent class. This class constructor will be used to inject dependencies in the object is given below figure.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace DependencyInjection

{

    public class OperationEvent

    {

        Ilog logger;

        public OperationEvent(Ilog logger)

        {

            this.logger = logger;

        }

         public void Division()

        {

            try

            {

                int AvgGain = 10000, AvgLoss = 0, rs;

                rs = AvgGain / AvgLoss;

                Console.WriteLine("Result is :{0}", rs);

            }

            catch (DivideByZeroException ex)

            {

                logger.Messagelog(ex);

            }

        }

    }

}

Here you notice that OperationEvent object is neither dependent on an Filelogger object nor anEventViewerLogger object so you can bale to inject either Filelogger dependencies oeEventViewerLogger dependencies at runtime.

Let’s see the EventViewerLogger dependencies in an OperationEvent object using constructor dependency injection.

using System;

namespace DependencyInjection

{

       class Program

    {

        

        static void Main(string[] args)

           {

               //Operation objOperation = new Operation();

               //objOperation.Division();

               //Console.Read();

               OperationEvent objOperationEvent = new OperationEvent(new EventViewerLogger());

               objOperationEvent.Division();

               Console.Read(); 

        }

    }

}

Now run your application and you get the result as below figure.

                           eventlog

Simple Dependency Injection with SignalR

Let’s consider the chat application with SignalR.

Here is the hub class from that application.

using Microsoft.AspNet.SignalR;

namespace SignalRChat

{   

        public void BroadCastMessage(string msgFrom,string msg)

        {

          Clients.All.receiveMessage(msgFrom,msg);

        }

    }

}

Now you want to store the chat messages on the server before sending them for those case, you might define an interface that abstracts this functionality, and use Dependency injection to inject the interface intoSignalRChatHub class.

namespace SignalRChat

{

    public interface IChatRepository

    {

        void Add(string msgFrom, string msg);

    }

}

using Microsoft.AspNet.SignalR;

namespace SignalRChat

{

 

    public class SignalRChatHub : Hub

    {

        private IChatRepository _Ichatresp;

        public SignalRChatHub(IChatRepository Ichatresp)

        {

            _Ichatresp = Ichatresp;

        }

        public void BroadCastMessage(string msgFrom,string msg)

        {

            _Ichatresp.Add(msgFrom, msg);

            Clients.All.receiveMessage(msgFrom,msg);

        }

    }

}

Here the problem is that a SignalR application does not directly create hubs for you.

SignalR creates them for you.by default SignalR expects a hub class to have parameter less constructor.However,you can easily resigter a function to create hub instance and use thid function to perform DI.

To register the function by calling GlobalHost.DependencyResolver.Resister

using Microsoft.AspNet.SignalR;

[assembly: OwinStartup(typeof(SignalRChat.Startup))]

namespace SignalRChat

{

    public class Startup

    {

        public void Configuration(IAppBuilder app)

        {

            GlobalHost.DependencyResolver.Register(

                                                    typeof(SignalRChatHub),

                                                    ()=> new SignalRChatHub(new IChatRepository()));

            app.MapSignalR();

        }

    }

}

Now SignalR will invoke this anonymous function whenever it needs to create a SingalChatHub instance.

The pervious code is fine for simple cases. I hope this article helps you.Thanks for reading this article.

 

Related

Microsoft Dynamics NAV 2013 R2 Multitenancy deployment

Multi-tenancy is a software architecture in which a single instance of the application can...

Read More >

Prerequistes for installing TestNG Framework in eclipse IDE

TestNG Introduction TestNG is an open source automated testing framework, where NG of Test...

Read More >

Accelerating Digital Transformation with GitHub

Hi All, in this blog I would like to share few insights on how you can leverage GitHub for your deve...

Read More >

Xamarin Forms- Dependency Service (Text To Speech)

Here I am going to explain you how we can use Text to Speech feature in Xamarin Forms without using ...

Read More >

Dynamics Team commences work on NAV Version Migration for a prestigious client in Malaysia

Canarys Dynamics Team is all excited and geared up to commence work on NAV Version Migration project...

Read More >

Openbravo Services

We are happy to announce our newly acquired partnership with Openbravo, Spain. Openbravo is the prov...

Read More >

Mobile Webinars Registration

h2{ margin-bottom:10px;}#wrapper{ margin: -40px auto 0; }#wrapper h1{ color:#FFF; text-align:center...

Read More >

Code Analysis & Code Metrics Integration in Azure Pipelines

This documentation shows the tutorial on how to integrate Visual Studio Code Analysis and Code Metri...

Read More >

T.F.S Webinars Registration

h2{ margin-bottom:10px;}#wrapper{ margin: -40px auto 0; }#wrapper h1{ color:#FFF; text-align:center...

Read More >

Microsoft Azure : Machine Learning - Price Prediction

We'll create linear regression model that predicts price of automobile based on different variab...

Read More >

Share

Try DevOpSmartBoard Ultimate complete Azure DevOps End-to end reporting tool

Sign Up

  • Recent
  • Popular
  • Tag
Monthly Archive
Subscribe
Name

Text/HTML
Contact Us
  • *
  • *