II. IOC Container AutoFac

First read the post:

https://www.cnblogs.com/bluesummer/p/8875702.html

 

Find out what's in this section:

Pragmatism, do it directly, first introduce the required nuget package, introduce the completion of the following figure:

Then, according to the post, modify the ConfigureServices method in Startup, add the following code in Startup, do not look at the post's response (build a class library alone) suggestions, and encapsulate it when needed.

The Configure function is also modified according to the post.

 

Okay, now there's the AutoofacModule class in the figure above.

Here's how the posts describe it

public class DefaultModuleRegister : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        //Register all interfaces implemented by the "Ser" end class in the current assembly, leak class, and lifecycle is PerLifetimeScope
        builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Ser")).AsImplementedInterfaces().InstancePerLifetimeScope();
        builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerLifetimeScope();
        //Register all classes in the "MyApp.Repository" assembly
        //builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();
    }

    public static Assembly GetAssembly(string assemblyName)
    {
        var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(AppContext.BaseDirectory + $"{assemblyName}.dll");
        return assembly;
    }
}

Baidu's other posts, and so on (need to have all the service names with Service)

protected override void Load(ContainerBuilder builder)
{
    builder.RegisterAssemblyTypes(this.ThisAssembly)
        .Where(t => t.Name.EndsWith("Service"))
        .AsImplementedInterfaces()
        .InstancePerLifetimeScope();
}

There are many ways to register Autofac. In the following post, personal feelings are more detailed:

https://www.cnblogs.com/tiantianle/p/5154742.html

 

The way called in Controller is as follows:

public IActionResult Index()
{
    using (var scope = Startup.AutofacContainer.BeginLifetimeScope())
    {
        IConfiguration config = scope.Resolve<IConfiguration>();
        IHostingEnvironment env = scope.Resolve<IHostingEnvironment>();
    }
}

There is no good or bad way to register, just suitable.

At present, the AutoFac container has been referenced.

Refer to AutoFac's service registration method described in the opening post below

// builder for Creating Registered Components
var builder = new ContainerBuilder();

//Register component ConsoleLogger leak service by type: ILogger
builder.RegisterType<ConsoleLogger>().As<ILogger>();

//Register the component ConsoleLogger according to its type, exposing all services (interfaces) that it implements
builder.RegisterType<ConsoleLogger>().AsImplementedInterfaces();

// Register component output leak service based on instance: TextWriter
var output = new StringWriter();
builder.RegisterInstance(output).As<TextWriter>();

//Expression registration component, where we are passing parameters during constructor - > "musection" leak service: IConfigReader
builder.Register(c =new ConfigReader("mysection")).As<IConfigReader>();

//Expressions register components and pass parameters during parsing
var service = scope.Resolve<IConfigReader>(
           new NamedParameter("section", "mysection"));     

//Reflective registration component, which directly registers the ConsoleLogger class (which must be a specific class), if ConsoleLogger has multiple constructors, the constructor with the most parameters will be instantiated.
builder.RegisterType<ConsoleLogger>();

//Reflect the registration component and specify the constructor manually. Here, you specify the constructor that calls MyComponent (ILogger log,IConfigReader config) for registration.
builder.RegisterType<MyComponent>()
 .UsingConstructor(typeof(ILogger), typeof(IConfigReader));  

 //Register the static variable "Instance" in the MySingleton class, and the ExternallyOwned() function specifies the lifetime of the instance it controls, rather than automatically released by autofac.
 builder.RegisterInstance(MySingleton.Instance).ExternallyOwned();

//One component leaks two services  
builder.RegisterType<CallLogger>().As<ILogger>().As<ICallInterceptor>(); 

//Register classes in the current assembly that end with "Service"
builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces();
//Register all classes in the "MyApp.Repository" assembly
builder.RegisterAssemblyTypes(GetAssembly("MyApp.Repository")).AsImplementedInterfaces();
  
//Build a container to complete registration
var rootcontainer = builder.Build();

//The implementation class of IConfigReader can be obtained manually in the following way
//This manual parsing approach requires getting components from the lifecycle scope to ensure that they are eventually released.
//Do not parse components directly from the root container rootcontainer, which is likely to lead to memory leaks
using(var scope = rootcontainer.BeginLifetimeScope())
{
  var reader = scope.Resolve<IConfigReader>();
}

For a specific component (class), the life cycle is divided into the following categories (the following functions are autofac functions):

Each dependent instance (Instance Per Dependency) (default) - - Instance Per Dependency ()
Single Instance Single Instance ()
Instance Per Lifetime Scope () -- Instance Per Lifetime Scope ()
Instance Per Matching Lifetime Scope ()
Instance Per Request (Instance Per Request) asp.net web request - Instance PerRequest ()
Instance Per Owned ()

2019/06/14 11:10

 

Posted by itarun on Thu, 22 Aug 2019 23:07:52 -0700