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

How to Host your Webpages on Google Drive

If you want to host your webpages quickly but don't have any web sever to host, then google driv...

Read More >

How to run NAV 2015 and NAV 2016 Administration tool side by side

Everyone would have installed NAV 2016 RTM and would have faced the same problem, i.e, you couldn...

Read More >

Quality is Our Mantra – Successful Completion of the Surveillance Audit

Canarys has successfully completed the Surveillance Audit and has been certified for ISO 9001:2008. ...

Read More >

Token Based Authentication for Web API's

Securing ASP.NET Web API using Custom Token Based AuthenticationProviding a security to the Web API&...

Read More >

Customer Feedback

Your feedback is important to us. Please share your experience working with Canarys & the journe...

Read More >

How to upload documents to SharePoint 2013

IntroductionSharePoint is a browser-based collaboration, content management, and extensible platform...

Read More >

DevOps Strategies for Enabling Efficient Application Development for Software Companies during COVID-19

The COVID-19 pandemic has been unprecedented, and the entire IT industry has been forced to rethink ...

Read More >

Git Command line Options

Git is a free and open source distributed version control system designed to handle everything from ...

Read More >

How to setup Module to Module communication in DotnetNuke

Are you building modules in DotnetNuke?Is one module depends on another module?Want to exchange data...

Read More >

Upcoming Webinar - Offshore support to North American Dynamics NAV partners

Offshore support to North American Dynamics NAV partners whose customers are moving to NAV '16Wh...

Read More >

Share

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

Sign Up

  • Recent
  • Popular
  • Tag
Tags
Monthly Archive
Subscribe
Name

Text/HTML
Contact Us
  • *
  • *