Step by step, learn EF series [6. IOC AutoFac] And iocautofac

Source: Internet
Author: User

Step by step, learn EF series [6. IOC AutoFac] And iocautofac

Preface

The first five articles are the basics of EF. Later we will use MVC + EF and use IOC, Repository, UnitOfWork, and DbContext for overall learning. Because IOC is used later, I will first learn about IOC. In this article, we will mainly learn Autofac. In fact, I also learn and record Autofac. I hope you can provide more guidance.

For more information about how to learn, see blog:

AutoFac documentation: http://www.cnblogs.com/wolegequ/archive/2012/06/09/2543487.html

AutoFac usage Summary: Part I: http://niuyi.github.io/blog/2012/04/06/autofac-by-unit-test/

Why is AutoFac used?

Autofac is one of the most popular IOC frameworks in the. NET field. It is said that it is the fastest:

 

Advantages:

  • It is closely related to the C # language. That is to say, many programming methods in C # Can Be Used for Autofac. For example, you can use Lambda expressions to register components.
  • Low learning curve, learning it is very simple, as long as you understand the concept of IoC and DI and when to use them
  • XML configuration support
  • Automatic Assembly
  • Integration with Asp. Net MVC
  • Microsoft's Orchad open-source program uses Autofac. It can be seen from the source code that it is convenient and powerful.

The above advantages are also copied from others' articles. Almost all of the above Autofac blog posts will appear. This is also the first learning, so we record a little more detail.

How to Use Autofac

 

Use NuGet in VS to load AutoFac. Autofac will appear after the import is successful.

1. Let's take a simple example first.

 

Take data access as an example. There are two types of data requests, one being Oracle and the other being SQLSERVER. We can choose to call the database when using it.

1.1 first, we define a data access interface and category class.
/// <Summary> /// data source operation interface /// </summary> public interface IDataSource {// <summary> /// obtain data /// </summary >/// <returns> </returns> string GetData ();}

 

/// <Summary> // SQLSERVER database // </summary> class Sqlserver: IDataSource {public string GetData () {return "get data through SQLSERVER ";}}

 

/// <Summary> // ORACLE Database // </summary> public class Oracle: IDataSource {public string GetData () {return "get data through Oracle ";}}

 

The most common way is for everyone! How can I write a SQL Server call in the most common way?

static void Main(string[] args)        {            IDataSource ds = new Sqlserver();            Console.WriteLine(ds.GetData());            Console.ReadLine();        }
If Oracle is called, new Oracle () can be used. If you cannot understand this, you will have a hard time learning this.

 

Improve the code. Let's take a look at the added javascemanager class.

/// <summary> 
/// Data source management class
/// </summary
Public class extends cemanager {IDataSource _ ds; /// <summary> /// dynamically create an object based on the input type /// </summary> /// <param name = "ds"> </param> public extends cemanager (IDataSource ds) {_ ds = ds;} public string GetData () {return _ ds. getData ();}}

What are the advantages of writing in this way? To Add a new data source, you only need to input this object during the call, and a corresponding object will be automatically created. Next, how do I write data if I want to call SQLSERVER. View code

DataSourceManager dsm = new DataSourceManager(new Sqlserver());
Console.WriteLine(dsm.GetData());Console.ReadLine();
1.2 inject constructor Injection

The above method of dynamic creation of DataSourceManager is because there is another constructor with IDataSource parameters. As long as the caller passes in the object that implements this interface, the object is created.

Let's see how to use AutoFac injection to implement constructor injection.

var builder = new ContainerBuilder();            builder.RegisterType<DataSourceManager>();            builder.RegisterType<Sqlserver>().As<IDataSource>();            using (var container = builder.Build())            {                var manager = container.Resolve<DataSourceManager>();                Console.WriteLine(manager.GetData());                Console.ReadLine();            }

 

The above is AutoFac constructor injection, which injects Sqlserver data to IDataSource, so we call the data, and the returned data is Sqlserver data. Next, let's take a look at some methods of AutoFac.

1.3 Autofac method description
(1) builder. RegisterType <Object> (). As <Iobject> (): The registration type and its instance. For example, the above is the instance of the IDataSource registration interface Sqlserver
(2) IContainer. Resolve <IDAL> (): resolves the instance of an interface. For example, I can parse the SQL server instance returned by the interface.

Var builder = new ContainerBuilder ();
// Builder. RegisterType <DataSourceManager> ();
Builder. RegisterType <Sqlserver> (). As <IDataSource> ();

Using (var container = builder. Build ())
{
Var manager = container. Resolve <IDataSource> ();
Console. WriteLine (manager. GetData ());

Console. ReadLine ();
}

(3) builder. RegisterType <Object> (). Named <Iobject> (string name): registers different instances for an interface. Sometimes it is inevitable that multiple classes map to the same interface. For example, both Sqlerver and Oracle implement the IDalSource interface. To obtain the desired type accurately, you must first name it at registration.
var builder = new ContainerBuilder();            builder.RegisterType<Sqlserver>().Named<IDataSource>("SqlServer");            builder.RegisterType<Oracle>().Named<IDataSource>("Oracel");            using (var container = builder.Build())            {                var manager = container.ResolveNamed<IDataSource>("Oracel");                Console.WriteLine(manager.GetData());                Console.ReadLine();            }
Code after running.
(4) IContainer. ResolveNamed <IDAL> (string name): resolves the "named instance" of an interface ". For example, the last line of the above instance code container. ResolveNamed <IDataSource> ("cancel") is to parse the name of the IDataSource instance named cancel.
(5) builder. RegisterType <Object> (). Keyed <Iobject> (Enum enum): register different instances for an interface in enumeration mode. Sometimes we use enumeration to differentiate different implementations of an interface, rather than strings.
This method can completely replace builder. RegisterType <Object> (). Named <Iobject> (string name). This column will not be demonstrated! And the above.
 
(6) IContainer. ResolveKeyed <IDAL> (Enum enum): parses a specific instance of an interface based on the enumerated value. This is the same as above and will not be demonstrated.
(7) builder. RegisterType <Worker> (). InstancePerDependency (): used to control the object lifecycle. Each time an instance is loaded, a new instance is created. This is the default method. Call
builder.RegisterType<Sqlserver>().Keyed<IDataSource>("Sqlserver").InstancePerDependency();
(8) builder. RegisterType <Worker> (). SingleInstance (): used to control the object lifecycle. The same instance is returned every time an instance is loaded.
(9) IContainer. Resolve <T> (NamedParameter namedParameter): assign a value to instance T when parsing. This is to pass the value to the parameter of the method you have defined.
IDataSource _ ds; string Name; /// <summary> /// dynamically create an object based on the input type /// </summary> /// <param name = "ds"> </param> public extends cemanager (string name, IDataSource ds) {_ ds = ds; Name = name;} public string GetData () {return Name + ":" + _ ds. getData ();}
I added a name parameter to the constructor of DataSourceManager. Then, when I call it:
Var manager = container. Resolve <export cemanager> (new NamedParameter ("name", "STONE Mr. Liu "));

Code after running:

 

1.4 Use AutoFac through Configuration

Demonstrate how to configure registration through the configuration file. Here is my web. config.

<configuration>  <configSections>    <section name="autofac" type="Autofac.Configuration.SectionHandler,Autofac.Configuration"></section>  </configSections>  <autofac defaultAssembly="AutoFacDemo">    <components>      <component  type="AutoFacDemo.Model.Oracle,AutoFacDemo" service="AutoFacDemo.Model.IDataSource" />    </components>  </autofac>  <startup>    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />  </startup></configuration>

 

Background call code

Var builder = new ContainerBuilder (); builder. registerType <DataSourceManager> (); builder. registerModule (new ConfigurationSettingsReader ("autofac"); using (var container = builder. build () {var manager = container. resolve <export cemanager> (new NamedParameter ("name", "STONE Mr. Liu"); Console. writeLine (manager. getData (); Console. readLine ();}

Note that you need to reference Autofac. Configuration. dll. Otherwise, there is no way to use ConfigurationSettingsReader.

Another thing to note is that your configuration file requires a namespace and the class name needs to be written to the correct name.

Try it!

 

Use Autofac under MVC

The reference is exactly the same as that of the console program above. But the difference is that you need to add another reference.

The case is still the use case. I copied the previous interfaces and classes to the MVC project for the following demonstration. The code is not written, exactly the same.

1. register your controller class in the Application_Start () function.

For how to configure MVC, you can directly read the following code. I wrote the annotations in great detail.

Protected void Application_Start () {AreaRegistration. registerAllAreas (); RouteConfig. registerRoutes (RouteTable. routes); // create the autofac container instance for managing the registration class var builder = new ContainerBuilder (); // you need to Register the Register method that can be managed for this container. // The Register Method of builder can be registered in multiple ways. several methods have been demonstrated in the console. Builder. registerType <Sqlserver> (). as <IDataSource> (); // builder. registerType <DefaultController> (). instancePerDependency (); // use the RegisterControllers extension method provided by Autofac to register all controllers in the Assembly at one time. registerControllers (Assembly. getExecutingAssembly (); // generate a specific instance var container = builder. build (); // The following describes how to use MVC extension to change the injection method in MVC. dependencyResolver. setResolver (new AutofacDependencyResolver (container ));}

It must be explained that:

1. Let's take a look at the following sentence. The purpose of this sentence is to register the Controller under MVC. Otherwise, there is no way to inject the Controller.

// Use the RegisterControllers extension method provided by Autofac to complete registration of all controllers in the Assembly builder. RegisterControllers (Assembly. GetExecutingAssembly () at one time ());

We can solve this problem by using RegisterControllers. So if I don't need RegisterControllers, how can I get them one by one? Learning Technology sometimes doesn't just use it. Sometimes you also need to understand what is behind the methods provided by others. Do you know how to do this? Consider it for 1 minute first. Do not remember to look down. The answer is actually mentioned when the console program used Autofac. Okay, let me explain in detail. I will first paste the code of the previous console program.

Public class extends cemanager {IDataSource _ ds; string Name; /// <summary> /// dynamically create an object based on the input type /// </summary> /// <param name = "ds"> </param> public extends cemanager (string name, IDataSource ds) {_ ds = ds; Name = name;} public string GetData () {return Name + ":" + _ ds. getData ();}}
Remember this class? I don't remember reading the previous article. This class has an IDataSource as the parameter constructor. Then let's take a look at the code for use?
Var builder = new ContainerBuilder (); builder. registerType <DataSourceManager> (); builder. registerType <Sqlserver> (). as <IDataSource> (); using (var container = builder. build () {var manager = container. resolve <export cemanager> (new NamedParameter ("name", "STONE Mr. Liu"); Console. writeLine (manager. getData (); Console. readLine ();}

Have you seen it? Container. resolve <DataSourceManager> () resolves the DataSourceManager instance through Resolve. For the DataSourceManager type, we provide the type for Autofac. However, when Autofac creates an DataSourceManager instance and calls its constructor, its constructor must provide an IDataSource instance as the parameter. Autofac will find the instance registered with IDataSource in its own container and use the AsImplementedInterfaces () method, indicates the instance provided for the IDataSource interface. It is then used as a parameter provided to the constructor when the DataSourceManager is created. I don't know how this works. Can you understand this?

If you didn't use RegisterControllers, how do you manually add them? The answer is to write several methods.

builder.RegisterType<DefaultController>().InstancePerDependency();
Note: DefaultController controller name. You can try to delete RegisterControllers and use the following sentence to try it. However, RegisterControllers is preferred in actual projects.

2. If builder. RegisterControllers <> is not written and the controller is not registered through builder. RegisterType <>, you will see the following error:

The configuration of the entire MVC using autofac is complete. Next, let's look at how to use the code.

2. Add a controller and inject dependent code
Public class DefaultController: Controller {IDataSource ds; // interface definition constructor injection public defacontroller Controller (IDataSource _ ds) {ds = _ ds;} // GET: Default public ActionResult Index () {// call a specific method of a specific class. The returned result is assigned to ViewBag. message ViewBag. message = "STONE Mr. Liu:" + ds. getData (); return View ();}}

The data requested by the entire function is added to ViewBag and displayed on the page, which is also relatively simple.

Effect after running:

Successful!

Add:

The column above demonstrates constructor injection, so let's see if it can be changed to attribute injection.

 

Conclusion

I finally finished AutoFac. If something is wrong, I thought you could give more advice and learn and make progress together. When I write a series of articles for the first time, I really admire everyone who shared them in the blog Park. This is really time-consuming and time-consuming. In the future, I should respect others' knowledge sharing.

 

You can also join the QQ group (435498053 ).

 

 

Author: Mr. STONE Source: http://www.cnblogs.com/liupeng/

The copyright of this article is shared by the author and the blog Park. You are welcome to reprint it. Without the consent of the author, the original article link and author must be clearly marked on the article page; otherwise, the legal liability is reserved.
If you think this article is good or rewarding, you can click the [recommendation] button in the lower right corner, because your support is the greatest motivation for me to continue writing and share it!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.