Dependency Injection in C#

Dependency Injection (DI, wikipedia) is a design pattern that reduces hard-coded dependencies between your classes by injecting these dependencies at run-time, instead of during design-time. Technically, Dependency Injection is a mechanism that allows the implementation of another, more high-level, design pattern called Inversion of Control (IoC, wikipedia). The purpose of both patterns is to reduce hard-coded dependencies (or ‘coupling’) between your classes.

 What are dependencies?

 Suppose that you are building a web application that is going to send e-mails to visitors that have entered a form. In object-oriented code, it is important to separate responsibilities. So you’ll probably end up with a class that handles the form input (FormHandler) and a class that is responsible for sending the e-mails (MailSender).

The MailHandler class looks like this:

public class MailSender
{
    public void Send(string toAddress, string subject)
    {
        Console.WriteLine(“Sending mail to [{0}] with subject [{1}]”, toAddress, subject);
    }
}

your FormHandler class will look like this:

public class FormHandler
{
   public void Handle(string toAddress)
     {
        MailSender mailSender = new MailSender();
        mailSender.Send(toAddress, “This is concrete code implementation example”);
     }
}

Although there’s nothing wrong with this code, it is creating a dependency between the FormHandler and MailSender classes.

The dependency is created at line MailSender mailSender = new MailSender();.

Using the New keyword in your code to instantiate a class implies that you are creating a dependency. From a practical point of view, you are telling your FormHandler class to use a concrete implementation of the MailSender class. There’s no flexibility. ‘But why’, you ask, ‘is this a bad thing?’. Let’s take a look at some reasons …

Why are dependencies a bad thing?

  • You can’t use multiple implementations of the MailSender class
  • It makes unit testing (nearly) impossible

The bottom-line is that your FormHandler shouldn’t know what concrete implementation of the MailSender is used. What concrete implementation is used, should be determined outside of your classes. That way, you can swap out the MailSender with another implementation if the need arises. If you are writing unit tests for the FormHandler, you can swap out the MailSender class with a mocked version.

we have to do is rewrite our code to use Interfaces. This is required for Dependency Injection, but is good practice anyways. An interfaces is basically a contract between classes that force one class to behave exactly as described by the interface. The contract can be implemented by other implementations (different class, same behavior).

We create a very straightforward interface for the MailSender class:

public interface IMailSender
{
    void Send(string toAddress, string subject);
}

We also rewrite the MailSender class to implement the IMailSender interface:

public class MailSender : IMailSender
{
    public void Send(string toAddress, string subject)
    {
        Console.WriteLine(“Sending mail to [{0}] with subject [{1}]”, toAddress, subject);
    }
}

We’ve basically told C# that the concrete implementation of our MailSender class follows the IMailSender interface (or contract). It is now possible to create other concrete implementations that follow the same interface but do different things ‘under the hood’,

for example:

public class MockMailSender : IMailSender
{
    public void Send(string toAddress, string subject)
   {
       Console.WriteLine(“Mocking mail to [{0}] with subject [{1}]”, toAddress, subject);
   }
}

Right now, we can change which concrete implementation is used by our FormHandler by rewriting the code where the class is instantiated:

public class FormHandler
{
    public void Handle(string toAddress)
    {
         IMailSender mailSender = new MockMailSender();
        mailSender.Send(toAddress, “This is still a concrete implementation “);
    }
}

Of course, this already adds a lot of flexibility to our code, as we can swap out which concrete implementation of IMailService is used by changing line IMailSender mailSender = new MockMailSender();.

Although C# will now force you to implement the IMailSender interface to the letter, your code will already improve a lot by using interfaces. The next step is to implement manual dependency injection to get rid of this code change that is required to change which implementation is used.

Implementing manual dependency injection:

 Basically, we’re going to pass the dependency in through the constructor of the FormHandler class. This way, the code that is using the FormHandler can determine which concrete implementation of IMailSender to use:

public class FormHandler
{
     private readonly IMailSender mailSender;

     public FormHandler(IMailSender mailSender)
     {
          this.mailSender = mailSender;
     }

    public void Handle(string toAddress)
     {
          mailSender.Send(toAddress, “This is manual dependency injection”);
      }
}

The code that creates our FormHandler has to pass in a concrete implementation of IMailService. This means that control is now inverted; instead of the FormHandler deciding which implementation to use, the calling code does. This is the whole point of Inversion of Control, of which Dependency Injection is just one approach. The calling code (the code that uses the FormHandler and now controls the dependencies) looks like this:

class Program
{
    static void Main(string[] args)
    {
        IMailSender mailSender = new MockMailSender();
        FormHandler formHandler = new FormHandler(mailSender);
        formHandler.Handle(“contact@uzval.com”);

        Console.ReadLine();
     }
}

 Concluding thoughts:

 Dependency Injection is a difficult concept to grasp if you’ve never used it before. Just give it a try, and you’ll see how flexible it makes your code. Especially when you’re writing unit tests you’ll quickly see the benefits. In that case, you can easily swap in mock implementations of dependencies. If anything, it makes your code a lot cleaner and sort of forces you to write better code.

UZVAL – Statistics – Total Hits-22,222, Total Visitors-6623, Total Posts – 93

Six years back I started posting certain postings in this blog for learning purpose.

Today it got 22,222 hits, Total Visitors-6623, Total Posts – 93.

During this tenure I had Learned a lot & Implemented my level best, Professionally & Personally.

Today i am feeling that i had completed one life cycle.

Heartful Thanks to My Well-Wishers who had given me good opportunities.

Now we all know lot of significant CHANGES (new versions, new libraries, new frameworks) evolved in .Net Stack.

Hope TOGETHER (Integrations & Collaborations) we learn and implement NEW needful CHANGES Professionally & Personally for a better life-style & society.

Sincerely,

Ujjwala Datta Kalluri.

uzval

If any Suggestion, please submit it below :

2015 in Review – Wish You Happy New Year

Wish You Happy Happy Happy New Year,

Time is free, but it’s priceless.
You can’t own it, but you can use it.
You can’t keep it, but you can spend it.
Once you’ve lost it, you can never get it back…

Years, Months, Weeks, Days, Hours , Minutes, Seconds… Its Transforming…

Hope we utilise our Time for well-being in a constructive way & we all have Good Health, Relationships, Prosperity, Contentment & Happiness.

Annual Report – 2015 for this blog

Here’s an excerpt:

In 2015 this blog was viewed about 5,300 times,

there were only 2 new posts,

The busiest day of the year was Apr 29th with 83 views.

Visitors are from 69 countries in all!

Most visitors came from India. The United States & The Srilanka.

Power of Concentration :)

Unwavering Focus | Dandapani | TEDxReno

Sharpening the needle of concentration requires practice, like everything else in life.

Do you go to the gym? If you do, how many times a week and for how long?

Have you studied a foreign language? If you did, for how long did you practice, until you had a basic knowledge of the language?

It is the same with developing your concentration. You need training and practice.

Your mind does not like discipline, and will resist your efforts to discipline it. It loves its freedom more than anything else, and won’t let you master it. It will make you forget to do the exercises, tempt you to postpone performing them, or make you feel too lazy. It will find many tricks to occupy your attention with something else.

If you find it too difficult, or thoughts distract you and make you think about other matters, don’t despair. Everyone encounters difficulties along the way. If you persevere and never give up, in spite of difficulties and disturbances, success will crown your efforts.

How to Improve THIS :

  • Take Rest

The biggest factor affecting concentration is rest and this has been approved by research. Concentration requires your mind to be calm. But your mind will be scattered if you are not well rested. Make sure that you get the right amount of sleep at the right time. Also have regular sleep time, and this can be the key step for concentrating.

Sleeping too much is also not ideal. Oversleeping disrupts your natural rhythm and can make you lazy. Avoid this by having an alarm clock to wake you up in time.

  • Make a Plan

Always have a plan for whatever you are up to. When you sit down to work without a plan, you may easily get caught in activities like checking mails, Instant messaging (chatting) and browsing the web. Without a purpose, you are wasting your time. You’ll find yourself distracted by a variety of nagging thoughts instead of devoting all your attention to one important task.

To avoid this, make a clear plan that meets your needs beforehand. Take 5 or 10 minutes break in between, and use this time to check email, and then close your inbox and move on to your most important task. When making a plan be sure to allocate enough time for entertainment, studies and sleep.

  • Meditate

The practice of meditation will definitely improve our powers of concentration. Actually, when we try to meditate, it is concentration that is the first thing we need to master. A daily period of meditation gives us the chance to work specifically on concentration techniques.

  • Choose a place of your choice for concentration

Obviously some places are better than others. Libraries, study lounges and private rooms are the best. Above all, the place that you choose should not be distracting. Try to stay away from other people if you want to concentrate on your work.

  • Develop a controlled and balanced diet

Overeating creates a huge load of digestion and can make you feel uncomfortable and sleepy. Eating light and healthy meals can help you maximize your ability to concentrate.

  • Exercise frequently

The ability to concentrate depends a lot upon our physical well-being. If we are tired, unhealthy and afflicted by numerous minor ailments, concentration will be more difficult. However, we have to try to make life easy for ourselves; we need to give a high priority to our physical health:

  • Getting sufficient sleep
  • Staying physically fit
  • Maintaining healthy weight
  • Getting regular exercise
  • Take breaks and mix up your environment

Continuous work in the same place can drive anyone crazy. Taking constant breaks can solve the problem. This will make you active and more interested in your topic.

  • Know that practice makes perfect

Do you jog, exercise at the gym, or study a foreign language? How difficult it was when you first started? How many times you wanted to quit? Despite the difficulties, after a while, you started to like what you were doing. It became a habit, and did not require special effort. So it is with developing the power of concentration.

After some practice, it will be easier to concentrate, and your mind will learn to be calm and relaxed. People, circumstances, and events that used to agitate and anger you, will not disturb you. You will experience happiness and contentment, and gain self-confidence and inner strength. You will be able to cope more easily and efficiently with the outer world.

SOFTWARE ARCHITECTURE – AN ARTIST HAS TO HAVE THE IMAGE IN MIND

 What are the key activities of a Software Architecture?

Philosophically, Architecture is an ART.

An architect thinks of something which doesn’t exist.

As a practice, a Software Architect is responsible for converting the business requirements into system blueprint, which can then acts as reference for design, implementation and other phases. Some of the key activities of an Architect, to list, are:

  • What is it– Describe and Define the system from a broader perspective, based on essential functional and non-functional requirements. Draw the blue print of the system.

  • Where it fits– Detailing on how the new solution would fit into and interface/communicate with other parts/systems of the whole eco-system.

  • What it contains– Visualize system as combination of sub-systems, parts/modules/functions and how these sub-systems will communicate/interface with each other. Define the system boundary, interface points/protocols and sub-system interactions.

  • How it is Structured– Choose appropriate Architectural pattern or combination of one or more and outline, how different sub-systems, modules, layers would be structured and interface with each other. For e.g. if chosen n-tier + SOA, then define different tiers and services exposed by them each and the way these tiers are connected.

  • How to build it– Define Technology Stake. Identify suitable frameworks/tools etc. Do a technical feasibility and evaluation exercise, if required.

  • What are Non-Functional Requirements– One of the important tasks of an Architect is to consider non-functional requirements applicable at Architecture phase for e.g. Scalability, Performance, Availability, Security etc.

  • How it is deployed– Consider Hardware architecture and infrastructure support required for this solution.

What are the key considerations while architecture an IT solution?

 Apart from implicit consideration that system should do what it is supposed to do, these are the important considerations from architecture perspective:

  • Money matters:The far most consideration is the overall cost involved in the solution. The solution should be cost effective, but still maintaining its value proposition.

  • Know Your Users (KYU): The solution should be easy to adopt and use. Many well architectured solutions have failed just because they are difficult to use and not adopted by user community. Know your users and make something which they can use.

  • Hear the unsaid:Along with key business functional requirements (which are mostly documented), the architect should consider the critical non-functional requirement to be addressed (which are, ironically, not always well documented and mentioned).

  • Anticipate Changes:The solution should be extensible and ready to accept (realistic) changes with minimal cost and efforts.

  • KISS: Keep it Short and Simple. Solution should be less complex and maintainable.

  • Make it Testable: Keep the testability in your mind. Something which can’t be tested, can’t be used.

What are key principles of software architecture?

  1. Separation of Concerns– Ensure that the system is divided into logical units, each performing its designated task(s) and there is no or least overlapping between these units. Don’t cross concerns. This helps in achieving loose coupling and logical partitioning of the system.

  2. Single Responsibility Principal– It is highly recommended to divide the system into units so that each has a single (logical) responsibility to handle and avoid multiple unrelated tasks.

  3. Principal of Least Knowledge (Low of Demeter)– This means each unit, component or object should know only about itself and has no knowledge about the internal details of others.

  4. Avoid Replication– Another key principle is to avoid repetition and maximize re-usability of component, logic, code etc.

 What are key non-functional requirements?

Non-functional requirements are one of the critical aspects of an IT solution. Ironically, those are not always well documented or candidly mentioned, but those are inevitable. Some of the important NFRs are

  • Run-time –Security, Performance, Scalability, Availability, Data Integrity

  • Implementation-timeComparability, Auditing, logging, localization, extensibility, maintainability, adaptability, testability.

What are key points to be considered for scalability of an IT solution?

Scalability is becoming an inevitable aspect for any IT solution, especially those involved customers interactions. Here are key points to be considered to address scalability:

  1. Functional Partitioning: It’s a very valid statement –you can’t scale if you can’t split. In other words, to achieve scalability you have to slice your application into logical modules or functions. This could be combination of functional or non-functional modules. With this, the modules or functions should be loose coupled, independent and, possibly, distributed. This allows these modules to scale independently.

  2. 3 Key Attributes of interaction/Communication

    1. State-less: One of the key needs of a scalable architecture is the provision of stateless interaction between different layers, components and modules. With no overhead of state management, 2 components or layers can scale independently with optimum utilization of each.

    2. Asynchronous: Another inevitable aspect is the asynchronous communication, using queues, messaging, batch processing etc. This would allow one layer to communicate with other, without holding the call. For e.g. if A wants to call B, A needn’t to wait till B finishes the job and vice versa. This also helps to ensure that A doesn’t stop even if B goes down or not available. Asynchronous is also the key for ‘Availability’ aspect of the solution.

    3. Service Oriented: One more important aspect is to have logical, atomic and granular level of communication, instead of multiple- fine grained calls. For e.g. if A wants to call B, B should expose services which are logical and granular enough to perform an operations. This would avoid A calling multiple times to B for the same functionality.

  3. For Database, 6 Key points

    1. Vertical Partitioning: Logically and physically divide the DB. Have relevant tables at one place and more disconnected in distributed manner.

    2. Horizontal Partitioning: Horizontally divide the DB (Shared or Table partitioning).

    3. No referential integrities: Avoid maintaining referential integrities in distributed environment. It’s a killer for scalable system.

    4. No Data integrity: (Read about CAP theory) Forget about data integrity in fast, distributed and scalable environment.

    5. No cross-domain joins – Avoid cross-domain joins. Those are expensive and time consuming.

    6. No distributed transactions

 And in the last, What are the key recommendations for a software Architect?

  • Visualize the System – If you can’t visualize or imagine the system, go back and clarify your doubts. An artist has to have the image in mind.

  • Always Keep 3 things in your mind – Business value, Cost and Time. Missing anyone will nullify all your efforts.

  • Make NFRs SMART – NFRs are critical, but unless those are Specific, Measurable, Attainable, Realizable and Traceable, those can’t be achieved.

  • Don’t Sketch Your Own Lines. Choose architecture patterns and practices which are established and accepted by Industry.

  • You may refer from your previous assignments and implement learning, but don’t biased from it. Technology is dynamic and improving everyday. Don’t hesitate exploring new paths.

  • It is important to document all Key decisions and learning.

    Architecture is not just an inception phase. Lead your team till the end. Don’t just define architecture, deliver it as well…

System Development Life Cycle

 The Systems Development LifeCycle (SDLC) is a type of methodology used to describe the process for building Information Systems, intended to develop System in a very deliberate, structured and methodical way, reiterating each stage (Investigation, Analysis, Design, Coading, Testing, Implementation, and Maintenance) of the life cycle.

In software engineering the SDLC concept underpins many kinds of Software Development Methodologies (Waterfall,V-model,Prototype,Spiral,RAD). These methodologies form the framework for planning and controlling the creation of a System.

Phases of SDLC:

  • Problem definition: On receiving a request from the user for systems development, an investigation is conducted to state
    the problem to be solved.

    • Deliverables: Problem statement (Requirements Gathering).
  • Feasibility study: The objective here is to clearly define the scope and objectives of the systems project, and to
    identify alternative solutions to the problem defined earlier.

    • Deliverables: Feasibility report.
  • Systems analysis phase: The present system is investigated and its specifications documented. They should contain
    our understanding of HOW the present system works and WHAT it does.

    • Deliverables: Specifications of the present system (Requirements Analysis).
  • Systems design phase: The specifications of the present system are studied to determine what changes will be needed
    to incorporate the user needs not met by the system presently. The output of this phase will consist of the specifications, which must describe both WHAT the proposed system will do and HOW it will work.

    • Deliverables: Specifications of the proposed system (System Architecture or Implementation Design).
  • Systems construction: Programming the system, and development of user documentation for the system as well as the
    programs.

    • Deliverables: Programs, their documentation, and user manuals.
  • System testing & evaluation: Testing, verification and validation of the system just built.

    • Deliverables: Test and evaluation results, and the system ready to be delivered to the user/client.