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

Sending Test reports by Email using Office 365, Gmail

Wouldn’t it be great if Test Report are sent automatically across team as soon the Test Execut...

Read More >

Displaying Postscript text and Vector images on PDF in C#.net using Imageglue

Postscript is a language used for creating vector Images,Vector images are made up of many scalable ...

Read More >

VMSS deployment Using Custom VM Image

In this blog we will see the VMSS update by using an image with Rolling upgrade policy.Prerequisites...

Read More >

Ansible Ad-Hoc Commands and Playbooks

An ansible ad-hoc command is a one-line command that lets you perform basic tasks efficiently withou...

Read More >

Canarys Automations Pvt Ltd recognized as finalist for 2017 Microsoft DevOps Partner of the Year Award

  Bengaluru, Karnataka, India — June 2, 2017 — Canarys Automations Pvt Ltd tod...

Read More >

Importing & Exporting Data in Microsoft Dynamics NAV 2013R2

     Since we all know In Microsoft Dynamics NAV 2013 R2, the support for t...

Read More >

Introduction to Azure DevOps Server (TFS) and Azure DevOps Services (VSTS)

In this blog we will talk about introduction to Azure DevOps Sever earlier called as Team Foundation...

Read More >

Building Xamarin.Android application in C#

OverviewIn this article we’ll look at how to create, deploy, and run a Xamarin.Android applica...

Read More >

GitHub Product Purchasing Details

In the previous blog we would have seen what GitHub is, who started this project and how it evolved ...

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
Text/HTML
Contact Us
  • *
  • *