The difference between autofac and other containers is that it is very closely integrated with the C # language, and has almost zero intrusion to your application during use, making it easier to integrate with third-party components, and open-source, autofac has the following main features:
1. flexible component instantiation: autofac supports automatic assembly. autofac automatically chooses to use constructor injection or attribute injection for a given component type. autofac can also create instances based on lambda expressions, this makes containers very flexible and easy to integrate with other components.
2. Resource Management visibility: the dynamic nature of applications built based on dependency injection containers means it is difficult to process those resources. Autofac uses containers to track component resource management. For objects that do not need to be cleared, such as console. Out, we call the externallyowned () method to tell the container not to clean up. Fine-grained component lifecycle management: an application usually has a container instance within the application scope, and a large number of objects within the request range exist in the application, for example, an HTTP request ends when an IIS worker thread or user session ends. Visualizes resources through nested container instances and object scopes.
3. The autofac design is very pragmatic. This is more important for the users of our containers:
● Zero component intrusion: The component does not need to reference autofac.
● Flexible modular system: Through Modular Organization of your programs, applications do not need to be entangled in complicated xml configuration systems or configuration parameters.
● Automatic assembly: You can use lambda expressions to register your components. autofac selects constructor or attribute injection as needed.
● Support for xml configuration files: xml configuration files are ugly during over-use, but they are usually useful for publishing.
Autofac is simple to use and added with the repository mode.
Define two simple object classes: public class persion {public string name {Get; set;} public int age {Get; Set ;}} public class custom {Public String customname {Get; set ;}public int customid {Get; Set ;}}
Define the generic database access interface: public interface idal <t> where T: Class {void insert (T entity); void Update (T entity); void Delete (T entity );}
Generic implementation of the generic database access interface: public class Dal <t>: idal <t> where T: Class {# region idal <t> Members public void insert (T entity) {httpcontext. current. response. write ("You added one:" + entity. getType (). fullname);} public void Update (T entity) {httpcontext. current. response. write ("You update one:" + entity. getType (). fullname);} public void Delete (T entity) {httpcontext. current. response. write ("You have deleted one:" + entity. getType (). fullname) ;}# endregion}
Use the repository mode for access.
Repository generic interface: public interface irepository <t> where T: Class {void insert (T entity); void Update (T entity); void Delete (T entity );}
Generic Implementation of the Repository generic interface: public class repository <t>: irepository <t> where T: Class {private idal <t> _ Dal; public repository (idal <t> DAL) {_ Dal = Dal;} # region irepository <t> Members public void insert (T entity) {_ Dal. insert (entity);} public void Update (T entity) {_ Dal. update (entity);} public void Delete (T entity) {_ Dal. delete (entity) ;}# endregion}
Idependency depends on the interface, no method body is required, and all business objects implement this interface public interface idependency {}
Implements the custombll class of the idependency interface and stores data in repository mode. Public class custombll: idependency {private readonly irepository <custom> _ repository; Public custombll (irepository <custom> repository) {_ repository = repository;} public void insert (custom C) {_ repository. insert (c);} public void Update (custom c) {_ repository. update (c);} public void Delete (custom c) {_ repository. delete (c );}}
Implements the persionbll class of the idependency interface and stores data in repository mode. Public class persionbll: idependency {private readonly irepository <persion> _ repository; Public persionbll (irepository <persion> repository) {_ repository = repository;} public void insert (persion P) {_ repository. insert (p);} public void Update (persion p) {_ repository. update (p);} public void Delete (persion p) {_ repository. delete (p );}}
Compile the component instantiation test below
VaR builder = new containerbuilder (); builder. registergeneric (typeof (DAL <> )). as (typeof (idal <> )). instanceperdependency (); builder. registergeneric (typeof (repository <> )). as (typeof (irepository <> )). instanceperdependency (); builder. register (C => New persionbll (irepository <persion>) C. resolve (typeof (irepository <persion>); builder. register (C => New custombll (irepository <custom>) C. resolve (typeof (ireposito Ry <custom>); // This line of code is used in the VaR Container = builder. Build () Tutorial. // you need to add the containerbuildoptions enumeration option to my local test. Using (VAR Container = builder. build (containerbuildoptions. none) {// var repository = container. resolve (typeof (irepository <persion>), new typedparameter (); // irepository <persion> _ repository = repository as repository <persion>; // var M = new persionbll (_ repository); persion P = new persion (); p. name = ""; p. age = 27; var M = container. resolve <persionbll> (); M. insert (p); custom c = new custom (); C. customname = ""; C. customid = 10; var cc = container. resolve <custombll> (); CC. update (c );}
Here, we use the containerbuilder method registergeneric to register generic classes (of course, we can also use the containerbuilder method registertype to register non-generic classes ), when the registered type is in the corresponding container, you can resolve your class instance.
Builder. registergeneric (typeof (DAL <> )). as (typeof (idal <> )). instanceperdependency (); you can use as to allow the class to inject corresponding interfaces of the type through the constructor dependency. (Of course, you can also use builder. registertype <class> (). As <interface> (); To register classes that are not generic)
The build () method generates a corresponding container instance, so that the registered type instance can be resolved through resolve.
Note: If you want to obtain a generic instance, you need to pass in the class represented by generic T. The Class C. Resolve (typeof (irepository <persion>) returns the object and needs to be converted to the response interface.
Of course, you can use registerassemblytypes, a new feature of autofac, to set the registration type from an Assembly according to the rules specified by the user, for example:
VaR builder = new containerbuilder (); builder. registergeneric (typeof (DAL <> )). as (typeof (idal <> )). instanceperdependency (); builder. registergeneric (typeof (repository <> )). as (typeof (irepository <> )). instanceperdependency (); // The classes above can be used if they are in a separate project, for example, if the generated assembly is autofacunittest. load ("autofacunittest") gets the response assembly. If all the files are in a console program, // you can directly obtain the corresponding Assembly through Assembly. getexecutingassembly. Assembly dataaccess = assembly. load ("autofacunittest"); builder. registerassemblytypes (dataaccess ). where (t => typeof (idependency ). isassignablefrom (t) & T. name. endswith ("BLL"); // The registerassemblytypes method implements the idependency interface and has registered all classes at the end of BLL. The syntax is very simple.
Detailed description of dependency injection container autofac