6. IoC is a design principle which recommends
inversion of different kinds of controls in object
oriented design to achieve loose coupling
between the application classes.
7. Here, the control means any additional
responsibilities a class has other than its main
responsibility, such as control over the flow of an
application, control over the dependent object
creation and binding (Remember SRP-Single
Responsibility Principle). If you want to do TDD
(Test Driven Development) then you must use IoC
principle without which TDD is not possible
8. DIP principle also helps in achieving loose coupling
between the classes. It is highly recommended to
use DIP and IoC together in order to achieve loose
coupling.
DIP suggests that high-level modules should not
depend on low level modules. Both should depend
on abstraction.
9. Dependency Injection (DI) is a design pattern
which implements IoC principle to invert the
creation of dependent objects.
10.
11. Inversion of Control (IoC) is a design principle
(although, some people refer to it as a pattern). As
the name suggests, it is used to invert different kinds
of controls in object oriented design to achieve loose
coupling. Here, the control means any additional
responsibilities a class has other than its main
responsibility, such as control over the flow of an
application, control over the flow of an object
creation or dependent object creation and binding.
12. IoC principle helps in designing loosely coupled
classes which make them testable, maintainable
and extensible.
13.
14. IoC can be applied to the above program by creating a
GUI based application such as the following windows
based application wherein the framework will handle
the flow of a program using events.
15. IoC can also be applied in the way we create
objects of dependent class. First of all, let's
understand what we mean by dependency here.
16.
17.
18.
19. Dependency Injection (DI) is a design pattern
used to implement IoC where it allows creation
of dependent objects outside of a class and
provides those objects to a class through
different ways. Using DI, we move the creation
and binding of the dependent objects outside of
the class that depends on it.
20. Dependency Injection pattern involves 3 types
of classes.
Client Class: The client class (dependent class) is
a class which depends on the service class
Service Class: The service class (dependency) is
a class that provides service to the client class.
Injector Class: The injector class injects service
class object into the client class.
21.
22. Constructor Injection: In the constructor injection,
injector supplies service (dependency) through the
client class constructor.
Property Injection: In property injection (aka Setter
Injection), injector supplies dependency through a
public property of the client class.
Method Injection: In this type of injection, client class
implements an interface which declares method(s) to
supply dependency and the injector uses this interface
to supply dependency to the client class.
23.
24. There are many open source or commercial containers
available for .NET. Some are listed below.
Unity
StructureMap
Castle Windsor
Ninject
Autofac
DryIoc
Simple Injector
Light Inject
25. Unity container is an open source IoC container
for .NET applications supported by Microsoft. It
is a lightweight and extensible IoC container.
Unity container source code is available
at https://github.com/unitycontainer/unity.
26. Simplified type-mapping registration for interface type or base type.
Supports registration of existing instance.
Supports code-based registration as well as design time registration.
Automatically injects registered type at runtime through constructor,
property or method.
Supports deferred resolution.
Supports nested containers.
Automatic disposing of instances based on lifetime managers such as
hierarchical, per resolve, externally controlled, per request and per
thread life time manager.
Supports service location capability; this allows clients to store or
cache the container
Supports type interception and instance interception.
Easy to extend unity container.
27.
28. Install Unity Container in Visual Studio
Register and Resolve
Constructor Injection
Property Injection
Method Injection
Overrides
Lifetime Managers in Unity Container
29.
30. The repository and unit of work patterns are
intended to create an abstraction layer
between the data access layer and the
business logic layer of an application.
Implementing these patterns can help insulate
your application from changes in the data store
and can facilitate automated unit testing or
test-driven development (TDD).
31.
32. In many applications, the business logic accesses data from
data stores such as databases, SharePoint lists, or Web
services. Directly accessing the data can result in the
following:
Duplicated code
A higher potential for programming errors
Weak typing of the business data
Difficulty in centralizing data-related policies such as
caching
An inability to easily test the business logic in isolation
from external dependencies
33. Use the Repository pattern to achieve one or more of the following
objectives:
You want to maximize the amount of code that can be tested with
automation and to isolate the data layer to support unit testing.
You access the data source from many locations and want to apply centrally
managed, consistent access rules and logic.
You want to implement and centralize a caching strategy for the data
source.
You want to improve the code's maintainability and readability by
separating business logic from data or service access logic.
You want to use business entities that are strongly typed so that you can
identify problems at compile time instead of at run time.
You want to associate a behavior with the related data. For example, you
want to calculate fields or enforce complex relationships or business rules
between the data elements within an entity.
You want to apply a domain model to simplify complex business logic.
34. Use a repository to separate the logic that
retrieves the data and maps it to the entity
model from the business logic that acts on the
model. The business logic should be agnostic
to the type of data that comprises the data
source layer. For example, the data source layer
can be a database, a SharePoint list, or a Web
service.
35. The repository mediates between the data source layer and the
business layers of the application. It queries the data source for
the data, maps the data from the data source to a business
entity, and persists changes in the business entity to the data
source. A repository separates the business logic from the
interactions with the underlying data source or Web service.
The separation between the data and business tiers has three
benefits:
It centralizes the data logic or Web service access logic.
It provides a substitution point for the unit tests.
It provides a flexible architecture that can be adapted as the
overall design of the application evolves.
36.
37.
38. Unit of Work is referred to as a single transaction
that involves multiple operations of
insert/update/delete and so on kinds. To say it in
simple words, it means that for a specific user
action (say registration on a website), all the
transactions like insert/update/delete and so on
are done in one single transaction, rather then
doing multiple database transactions. This means,
one unit of work here involves
insert/update/delete operations, all in one single
transaction.
Notas do Editor
Design patterns are typical solutions to common problems
in software design. Each pattern is like a blueprint
that you can customize to solve a particular
design problem in your code.
Patterns are a toolkit of solutions to common problems in software design. They define a common language that helps your team communicate more efficiently.
The terms Inversion of Control (IoC),
Dependency Inversion Principle (DIP),
Dependency Injection (DI),
and IoC containers may be familiar.
But are you clear about what each term means?
DIP principle is invented by Robert Martin (a.k.a. Uncle Bob). He is a founder of SOLID principles. Learn about DIP in the DIP chapter.
The IoC container is a framework to manage automatic dependency injection throughout the application so that we as a programmer do not need to put more time and effort on it.
There are various IoC Containers for .NET such as Unity, Ninject, StructureMap, Autofac etc. We will learn more about it in the IoC Container chapter.
We cannot achieve loosely couplde classes by only using IoC. Along with IoC we also need to use DIP, DI and IoC container. The following figure illustrates how we are going to achieve loosely coupled design step by step in the next few chapters.
IoC is all about inverting the control. To explain in layman's term, suppose you drive a car to your work place, it means you control the car. IoC principle suggests to invert the control, meaning instead of driving the car yourself, you hire a cab where another person will drive the car. Thus it is called inversion of the control from you to the cab driver. You don't have to drive a car yourself and let the driver do the driving so that you can focus on your main work.
In a typical console application in C#, execution starts from the Main() function. The Main() function controls the flow of a program or in other words sequence of user interaction. Consider the following simple console program
In the above example, the Main() function of the program class controls the flow of a program. It takes user's input for the first Name and last name. It saves the data, continues or exits the console depending upon the user's input. So here, flow of the control through the Main() function.
This is a simple example of implementing IoC on the flow of a program.
As you can see above, class A uses Factory class to get an object of class B. Thus, we have inverted the dependent object creation from class A to Factory. The class A no longer creates an object of class B instead it uses Factory class to get the object of class B.
In an object oriented design, classes should be designed in loosely coupled way. Loosely coupled means changes in one class should not force other classes to change, so the whole application can become maintainable and extensible
In the typical n-tier architecture, the User Interface (UI) uses Service layer to retrieve or save the data. The service layer uses the BusinessLogic class to apply business rules on the data. The BusinessLogic class depends on the DataAccess class which retrieves or saves the data to the underlying database. This is simple n-tier architecture design. Let's focus on the BusinessLogic and DataAccess class to understand IoC.
As you can see, injector class creates an object of service class, and injects that object to a client object. This way DI pattern separates the responsibility of creating an object of service class out of client class.
In the method injection, dependencies are provided through methods. This method can be a class method or interface method.
The following example demonstrates method injection using interface based method.
Implement Unity features
The following illustration shows one way to conceptualize the relationships between the controller and context classes compared to not using the repository or unit of work pattern at all.
There are two ways that the repository can query business entities. It can submit a query object to the client's business logic or it can use methods that specify the business criteria. In the latter case, the repository forms the query on the client's behalf. The repository returns a matching set of entities that satisfy the query. The following diagram shows the interactions of the repository with the client and the data source.
The client submits new or changed entities to the repository for persistence. In more complex situations, the client business logic can use the Unit of Work pattern. This pattern demonstrates how to encapsulate several related operations that should be consistent with each other or that have related dependencies. The encapsulated items are sent to the repository for update or delete actions. This guidance does not include an example of the Unit of Work pattern. For more information, see Unit of Work on Martin Fowler's Web site.
The unit of work class serves one purpose: to make sure that when you use multiple repositories, they share a single database context. That way, when a unit of work is complete you can call the SaveChanges method on that instance of the context and be assured that all related changes will be coordinated. All that the class needs is a Save method and a property for each repository. Each repository property returns a repository instance that has been instantiated using the same database context instance as the other repository instances.