Autofac IOC

 Autofac会提供3种生命周期当我们,支持.NET和.NET CORE


1.Instance Per Dependency

推荐 

每次都会返回一个新的实例,并且这是默认的生命周期。

var builder = new ContainerBuilder();

// This...
builder.RegisterType<Worker>();

// 此句代码的效果同上
builder.RegisterType<Worker>().InstancePerDependency();



2、Instance Per Lifetime Scope

推荐 

在同作用域,服务每个请求只创建一次。 

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().InstancePerLifetimeScope();



3、Single Instance   

不推荐 ,这种模式很容易出问题

静态的 ,所有请求一个实例

var builder = new ContainerBuilder();
builder.RegisterType<Worker>().SingleInstance();

单例模式下的常见错误用法 ,该代码只有在Singleton模式下才会有问题

public class Worker:DbContext
{
    
}
public class DbContext
{
   public SqlSugarClient Db;//这个时候因为Worker给静态变相的Db也变成静态的了
   public DbContext(){
      Db=new SqlSugarClient(....);
   }
}

如果你非要用 Single Instance模式你的代码就需要用出调整:

public class DbContext
{
   public SqlSugarClient Db 
   get{
      
      return new SqlSugarClient(...);//每调用Db都会new一个新的SqlSugarClient
   }
   
}

//如果要用到事务不能每次都new
var db=Db;
db.xxx;
db.xxxx; //这样在一个方法都可以用一个db对象不会new

改成这样你就能用单例模式了,不过还是不推荐用单例模式





.NET Core 3.x mvc 使用Autofac

如果没用过Autofac IOC的我们从零开始学起


1、创建MVC项目

默认MVC是不支持路由的,需要在Startup.cs里面加入

  app.UseEndpoints(endpoints =>
  {
     endpoints.MapControllerRoute
     (name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
     endpoints.MapControllerRoute
     ("areaRoute", "{area:exists}/{controller=Admin}/{action=Index}/{id?}");
  });

然后删除自带的Pages

在根目录创建Controllers文件夹和Views文件夹


2、配置Autofac 

2.1 安装Nuget

Autofac和

Autofac.Extensions.DependencyInjection


2.2  修改Program

  public class Program
  {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
                     Host.CreateDefaultBuilder(args)
                .UseServiceProviderFactory(new AutofacServiceProviderFactory())//添加这一行
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
  }


2.3 修改Startup

     public void ConfigureServices(IServiceCollection services)
     {
            services.AddRazorPages();
            services.AddControllers().AddControllersAsServices();//-----------------添加这一行
      }

     public void ConfigureContainer(ContainerBuilder builder) //----------------添加这个方法
     {
            builder.RegisterType<OrderDal>().InstancePerLifetimeScope();
            var webAssemblytype = typeof(Program).Assembly;
            builder.RegisterAssemblyTypes(webAssemblytype).PropertiesAutowired();
      }


3、控制器里面使用注入

 public class HomeController : Controller
 {
        public OrderDal order { get; set; }//定义他就能注入了
 
        public IActionResult Index()
        {
            var list = order.GetList();
            return View();
        }
 }

BLL层定义一个类

 public class OrderDal : Repository<Order>
 {
 
 }
 //如果不会定义Repository<Order> 
 //查看文档仓储定义 http://www.codeisbug.com/Home/Doc?typeId=1228