Objective
The first contact AUTOFAC because CMS system--orchard, and later in an open source crawler system--ncrawler also encountered, with in-depth understanding, I increasingly feel that the IOC container is an indispensable tool in web development. So what is the IOC container for? What are the benefits of using it? I believe it would be difficult to open up to the IOC container without understanding these two points.
Disadvantages of traditional decoupling design
For the convenience of description, raise a log of chestnuts. I simplify the implementation, a log class, a Savelog method. If other classes want to have logging capabilities, then just include a variable of type log inside:
public class Log
{
public void Savelog (String message) {
Save log here.
}
}
public class Productservice {
Private Log _log;
Public Productservice () {
_log = Newlog ();
}
public void Saveproduct () {
Save product here.
//...
_log. Savelog ("Save 1 Product");
}
}
An experienced programmer may tell you that doing so will cause other classes to be coupled to log. So, to understand the decoupling, we abstracted the function of the log class, and the Ilog interface was created. As a result, when other classes require log functionality, the embedded variable changes from log to Ilog:
Public interface ILog {
void Savelog (String message);
}
public class Log:ilog
{
public void Savelog (String message)
{
Save log here.
}
}
public class Productservice
{
Private ILog _log;
Public Productservice ()
{
_log = Newlog ();
}
// .......
}
Because Ilog is abstracted out, its implementation class can be diversified, saved as TXT, XML, database, and even extensible email notification function. Basically, I see in the domestic project, so-called decoupling can only go to this step, but this design is really so-called "flexible, easy to expand, cohesion, low coupling"?
Now, let's simulate demand changes. Suppose the Txtlog class has saved the log as a TXT file, but after a period of time it is found that the log is difficult to query. The project manager decides to save the log to the database, and the DBLog class emerges. But as the entire system is flooded with new Txtlog (), the conversion process is essentially a process of finding txtlog replacing DBLog. At this time, the size of the project to determine the error rate, the error caused by incomplete logging, the record does not completely cause the system failure to find the log, not found the cause of the log, can not find the cause of overtime, the consequences are too serious.
Suddenly, the climax, the manager or the boss decided to change back to txt or another form of log, unexplained, or save costs, or experience bad, or suitors slanderers, or mean to play with you, or with the database has a feud, in short--TMD is to change. So, the tragic search replaced again staged, a few toss, riddled with holes.
And at this point, do you still admire the design as "flexible, easy to expand"?
Moving into the IOC gate-changing the way it's instantiated
Now we use the IOC container--AUTOFAC to improve the code above, the goal is to eliminate the new statement in the code, to transfer the control of the instantiated class to another place, this place is usually in a program load only once in the global method.
public class Global {
public static IContainer container;
public void Application_Start () {
Containerbuilder Builder=newcontainerbuilder ();
Builder. Registertype<log> (). As<ilog> ();
Builder. Registertype<productservice> ();
container = Builder. Build ();
var productservice = container. Resolve<productservice> ();
}
}
public class Productservice
{
Private ILog _log;
Public Productservice (ILog log)
{
_log = log;
}
// .......
}
In the above code, Containerbuilder and IContainer are the core classes in AUTOFAC (later in this article, not described in this article). When we want to instantiate a productservice, we need to write the following code:
var productservice = container. Resolve<productservice> ();
There is no log-related operation, but the _log variable in Productservice has been assigned a log instance. The IOC container matches the type of the instantiated parameter in the registered component (class or interface), and once the type is found to be registered, the corresponding instance is automatically assigned to that type, which is called the constructor injection.
Look back at that once tortured our txtlog to change the dblog of the question, the blessing of the IOC, as long as in that global approach to change the type to solve.
IOC is more than just controlling rollover
Perhaps you would say that this chestnut is a bit extreme, the actual development of the search for replacements is not much, and the IOC just to instantiate a place to go, for such a little profit to pay a huge cost of learning, is it worthwhile?
In fact, in addition to controlling inversion, the IOC provides a lot of control over the life cycle of the instance, and the AUTOFAC used in this article provides simple integration modules for popular frameworks such as MVC,WCF, as well as dynamic proxy capabilities. How do I add logic to a method in a class without modifying the original code? The Orchard Framework designs an interesting architecture through the AUTOFAC and Dynamicproxy libraries to combine the method logic of two unrelated classes. For more details, I'll show you in a later series of articles.
IOC Container AUTOFAC Series (1)--First Glimpse