Autofac official document translation - a registered component --1 registered concept

Official documents: http: //docs.autofac.org/en/latest/register/registration.html

First, the concept of registration

  Use Autofac registration component, by creating a ContainerBuilder and inform builder which public service which components.

  Components of reflection (by registering a particular type or open .net generics) creation; creation by providing ready-made instance (an object instance that you have created); or created by the lambda expression. ContainerBuilder a series of Register () method that allows you to achieve these settings.

  By use of As () method of ContainerBuilder, each component disclosed in one or more services.

Copy the code
// Create the component / service container registered 
var = new new ContainerBuilder Builder (); 

// registration type disclosed Interface 
builder.RegisterType <ConsoleLogger> () of As <ILogger> ();. 

// Register you create an object instance 
var output = StringWriter new new (); 
builder.RegisterInstance (the Output) the .as <TextWriter> (); 

// registered execution expression creates an object 
builder.Register (c => new ConfigReader ( "mysection")) As <IConfigReader> (). ; 

// compile complete the registration and preparation container objects parse 
var = builder.Build container (); 

.. // now you can use Autofac resolution service for example, it is about to perform the registration of a lambda expression for IConfigReader service 
using (var scope = container .BeginLifetimeScope ()) 
{ 
  var Reader = container.Resolve <IConfigReader> (); 
}
Copy the code

 

1, reflective assembly

1.1 By type registration

Component generated by the reflection type is generally registered by:
var builder = new ContainerBuilder();
builder.RegisterType<ConsoleLogger>();
builder.RegisterType(typeof(ConfigReader));

When using a reflection component, Autofac automatically for your class, the constructor has the most matching parameters, this parameter can be obtained from the container.

For example, you have a class with three constructors:

public class MyComponent
{
    public MyComponent() { /* ... */ }
    public MyComponent(ILogger logger) { /* ... */ }
    public MyComponent(ILogger logger, IConfigReader reader) { /* ... */ }
}

Now, components and services registered in your container:

Copy the code
var builder = new ContainerBuilder();
builder.RegisterType<MyComponent>();
builder.RegisterType<ConsoleLogger>().As<ILogger>();
var container = builder.Build();

using(var scope = container.BeginLifetimeScope())
{
  var component = container.Resolve<MyComponent>();
}
Copy the code

When you parse your components, Autofac will find already registered ILogger, but not registered IConfigReader. In this case, the second constructor will be selected, because it has the largest is a constructor parameter can be found in the container.

Note that based on the reflected components: Component Type RegisterType must be registered by a particular type. While the components can be made public abstract classes and interfaces as a service, but you can not register an abstract class / interface components. If you think about it makes sense: Inside Autofac, Autofac create an object instance you register. You can not be a new abstract class or an interface. You must have an implementation of it.

1.2 Specify a constructor

You can manually select a specific constructor, and the cover is used to automatically select register assembly constructor, and a set of methods using UsingConstructor type parameter indicating the type constructors:

builder.RegisterType<MyComponent>()
       .UsingConstructor(typeof(ILogger), typeof(IConfigReader));

Please note that when parsing, you still need to provide the necessary parameters, otherwise an error when you attempt to resolve the object appears. You can pass parameters when registering or pass parameters when parsing.

2, examples of the component

Sometimes, you may want to generate early instance of an object, and add it to the container for the component to sign up. You can do so using the RegisterInstance method:

var output = new StringWriter();
builder.RegisterInstance(output).As<TextWriter>();

When you do some things to consider, Autofac automatic registration process release component, or do you want to control your life cycle rather than Autofac call Dispose for you on your object. In this case (you want to control the life cycle), you need to use the method to register ExternallyOwned instance:

var output = new StringWriter();
builder.RegisterInstance(output)
       .As<TextWriter>()
       .ExternallyOwned();

When Autofac integrated into an existing application (singleton instance already exists a need and use as a component in a container), also provides examples of registration handy, these components not directly tied to a single embodiment of the , which can be registered in a container as an example:

builder.RegisterInstance(MySingleton.Instance).ExternallyOwned();

This will ensure that static singleton may eventually be phased out and replaced by a container management.

The default service is disclosed by way of example of a particular type. See "services and components" below.

3, Lambda expressions assembly

For reflection component creation is a very good default choice. When you create a logical component is not just a simple constructor call, things will get messy.

Autofac to accept a delegate or lambda expression is used to create the components:

builder.Register(c => new A(c.Resolve<B>()));

Expression parameter c is provided a context component (a IComponentContext object), where the assembly is created. You can use it to resolve other components from the container to help you create components. It is important to use it, instead of a closure to access the container, so that the correct support and custom built containers clean up.

Use additional context parameter dependencies may be used - in this case, A is required the constructor parameter of type B, may have additional dependencies.

Services provided by default expression-created component is the expression inferred return type.

Here are some examples of the demand created by the reflected component is very clumsy, but by the lambda expression is very nice to deal with.

  • Complex parameters
The constructor parameters are not always a simple constant value statement. XML configuration values ​​without using some type of grammatical structure, using the code:
builder.Register(c => new UserSession(DateTime.Now.AddMinutes(25)));

Of course, you may want to specify the session expires something in the configuration file. 

  • Properties injection
Although Autofac provide a first-class property injection, you can also use initialization expressions and attributes to fill characteristics:
builder.Register(c => new A(){ MyB = c.ResolveOptional<B>() });

This ResolveOptional method attempts to resolve values, but if the service is not registered, will not throw an exception. (You will get an exception if the service is registered but the property has not been resolved). This is one way to resolve the service.

Not recommended for use property injection in most cases. Alternatively null object mode, reloading the default values ​​constructor or a constructor parameter may create a cleaner, "change" components can be used constructor dependency injection.
  • An implementation (Selection of an Implementation by Parameter Value) parameter values ​​by selecting
Separate components to create the greatest advantage is the specific type can change, which is usually running is done, and not just when you configure:
Copy the code
builder.Register<CreditCard>(
  (c, p) =>
    {
      var accountId = p.Named<string>("accountId");
      if (accountId.StartsWith("9"))
      {
        return new GoldCard(accountId);
      }
      else
      {
        return new StandardCard(accountId);
      }
    });
Copy the code

In this example, CreditCard two classes implement, GoldCard and  StandardCardwhich depends on the class is instantiated to provide runtime accountId.

In this example, the method of creating the second parameter provided by the parameter p.

Use the code below to register:

var card = container.Resolve<CreditCard>(new NamedParameter("accountId", "12345"));
If a delegate creates CreditCard instance declaration and a delegate factory, you can get a clean, safe type of syntax. 

4, common components disclosed (Open Generic Components)

 

Autofac support open generic type, use RegisterGeneric () constructor:

 

builder.RegisterGeneric(typeof(NHibernateRepository<>))
       .As(typeof(IRepository<>))
       .InstancePerLifetimeScope();
When the container needs to type a matching service, autofac will be mapped to an equivalent of close to achieve the type of version.
// Autofac will return an NHibernateRepository<Task>
var tasks = container.Resolve<IRepository<Task>>();
Proprietary type of service (eg IRepository <Person>) registration will rewrite the generic version.

5, services and components (Services vs. Components)

When you register components, which you must tell the public service autofac component, by default, only the most publicly registered themselves as the type of registration.
// This exposes the service "CallLogger"
builder.RegisterType<CallLogger>();

Components can only be resolved their public services, in this simple example, it means:

// this will work, because the default public assemblies of this type 
scope.Resolve <CallLogger> (); 

// this will not work, because we have not registered nor disclose ILogger interfaces 
scope.Resolve <ILogger> ();
You can use any number of public service component.
builder.RegisterType<CallLogger>()
       .As<ILogger>()
       .As<ICallInterceptor>();
Once a public service, you can resolve the component-based services. Note, however, once you open as a component of a particular service, the default service (component type) will be covered:
// these will work, because we open a corresponding service in the registry 
scope.Resolve <ILogger> (); 
scope.Resolve <ICallInterceptor> (); 

// This will not work, because we have developed a special rewriting the service component 
scope.Resolve <CallLogger> ();
If you want to open a component is a set of services and use the default service, you can use AsSelf method:
builder.RegisterType<CallLogger>()
       .AsSelf()
       .As<ILogger>()
       .As<ICallInterceptor>();

Now, all of which will work:

// These will all work because we exposed
// the appropriate services in the registration:
scope.Resolve<ILogger>();
scope.Resolve<ICallInterceptor>();
scope.Resolve<CallLogger>();

6, the default registration (Default Registrations)

If multiple components with a public service, autofac will use the final component registered as the default service provider:
builder.Register<ConsoleLogger>().As<ILogger>();
builder.Register<FileLogger>().As<ILogger>();

In this case FileLogger will ILogger provider as the default service, as it was last registered.

In order to overthrow this case, you can use the  PreserveExistingDefaults()method to modify:

builder.Register<ConsoleLogger>().As<ILogger>();
builder.Register<FileLogger>().As<ILogger>().PreserveExistingDefaults();
In this case, ConsoleLogger will ILogger provider as the default service, because the last registered FileLogger used PreserveExistingDefaults ().
 

7, the configuration register (Configuration of Registrations)

You can configure "modules" to provide a set of registration or change registration at runtime using XML or programming. Autofac modules may be used to generate or provide dynamic registration condition register logic.

8, provide dynamic registration (Dynamically-Provided Registrations)

Autofac modules for registration introduced Dynamic Logic is the easiest way. You can use when parsing a module dynamically add a log4net log instance as a service,
If you need more dynamic characteristics, such as adding a new type of relationship implicit support, you may want to use advanced concepts check the registration source part.

Guess you like

Origin www.cnblogs.com/nimorl/p/12626452.html