.NetCore 3.1 使用AutoFac实现Autowired

我们知道,.NetCore 中友好的IOC容器可以帮助我们很方便的创建对象的实例。

通常我们在构建了一个 .NetCore 项目,是使用构造函数的方式获取对象的实例,然后再将实例的对象赋值在本类的属性中,这种方式在本类使用的外部对象少时还好,但是多的时候,就会显得很臃肿,不够优雅。

熟悉 Java 同学都知道,Java 有 @Autowired 注解,可以很方便的获取对象实例,代码又很优雅,那我们是否可以在.Netcore 中也可以如此优雅的进行对象实例呢?答案是可以的。

 

在 Program 中增加 

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

 

 

创建 AutoRegisterModule 继承 Autofac.Module(这里要注意,BaseApiController 是封装的 ControllerBase,如果你没有进行封装,请替换 BaseApiController 为 ControllerBase 

public class AutoRegisterModule : Autofac.Module
{
    protected override void Load(ContainerBuilder builder)
    {
        // 自动对集成 IDependency 接口的类进行注册
        Type baseType = typeof(IDependency);
        var compilationLibrary = DependencyContext.Default
            .CompileLibraries
            .Where(x => !x.Serviceable
            && x.Type == "project")
            .ToList();

        List<Assembly> assemblyList = new List<Assembly>();
        foreach (var _compilation in compilationLibrary)
        {
            try
            {
                assemblyList.Add(AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(_compilation.Name)));
            }
            catch (Exception ex)
            {
                Console.WriteLine(_compilation.Name + ex.Message);
            }
        }
        builder.RegisterAssemblyTypes(assemblyList.ToArray())
            .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
            .AsSelf()
            .AsImplementedInterfaces()
            .PropertiesAutowired()
            .InstancePerLifetimeScope();

        //在控制器中使用属性依赖注入,其中注入属性必须标注为 public  
        //注意属性注入 发现为Null  需要在Startup.cs  的 ConfigureServices 方法下加入如下代码
        //services.AddControllers().AddControllersAsServices();
        var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
            .Where(type => typeof(BaseApiController).IsAssignableFrom(type)).ToArray();

        builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();

    }
}

 

 

在 Startup 的 ConfigureServices 中增加

public void ConfigureServices(IServiceCollection services)
{
    
    //上面是其他的实现

    services.AddControllers().AddControllersAsServices();
}

 

 

在 Startup 的 ConfigureContainer 中增加

public void ConfigureContainer(ContainerBuilder builder)
{ 
    //添加依赖注入实例,AutofacModuleRegister就继承自Autofac.Module的类
    builder.RegisterModule<AutoRegisterModule>();
}

 

 

定义完毕,以下是使用方式。

 

定义一个Service 

public class TestService : IDependency
{
    public string GetString()
    {
        return "hello jd";
    }
}

 

在 Controller 中使用他

public class Test1Controller : BaseApiController
{
    public TestService service { get; set; }

    [HttpGet, Route("demo")]
    public string GetDemo()
    {
        string str = service.GetString();

        return "demo";
    }
}

 

 

以上就是使用AutoFac实现Autowired的完整过程了,实践过程中有问题欢迎留言讨论。

 

posted @ 2021-09-17 17:55  大山楂丸子  阅读(548)  评论(0编辑  收藏  举报